[med-svn] [python-intervaltree-bio] 01/02: Imported Upstream version 1.0.1
Afif Elghraoui
afif-guest at moszumanska.debian.org
Sun Dec 13 07:59:22 UTC 2015
This is an automated email from the git hooks/post-receive script.
afif-guest pushed a commit to branch master
in repository python-intervaltree-bio.
commit a6d415a36c5b068e731cb8e4abfa5225acfd198e
Author: Afif Elghraoui <afif at ghraoui.name>
Date: Sat Dec 12 15:36:33 2015 -0800
Imported Upstream version 1.0.1
---
.gitignore | 5 +
.travis.yml | 8 ++
CHANGELOG.txt | 16 +++
LICENSE.txt | 21 ++++
MANIFEST.in | 1 +
README.rst | 47 ++++++++
intervaltree_bio/__init__.py | 230 +++++++++++++++++++++++++++++++++++++++
setup.cfg | 9 ++
setup.py | 54 +++++++++
tests/__init__.py | 10 ++
tests/genomeintervaltree_test.py | 54 +++++++++
tests/pickle_test.py | 22 ++++
12 files changed, 477 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7d9f84e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.pyc
+.DS_Store
+*.egg-info
+*.komodoproject
+dist/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..a6cfe31
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+language: python
+python:
+ - "2.7"
+ - "3.2"
+ - "3.3"
+ - "3.4"
+script:
+ - python setup.py develop test
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..4982b68
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,16 @@
+Version 1.0.1
+-------------
+
+ - GenomeIntervalTree may now be pickled.
+
+Version 1.0.0
+-------------
+
+ - Replaced dash in the package name to underscore, as it seemed to confuse the package manager (python setup.py develop would fail on packages attempting to use intervaltree).
+ Formally, it's a new package now. The package with the dash in the name had to be removed completely from PyPI
+ - Added the the possibility to specify an interval_maker in GenomeIntervalTree's methods from_bed and from_table.
+
+Version 0.6
+-------------
+
+ - Extracted genome-related code into a separate package from https://github.com/konstantint/PyIntervalTree (version 0.5).
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..5a59174
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015, Konstantin Tretyakov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..e7d1090
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include README.rst CHANGELOG.txt LICENSE.txt
\ No newline at end of file
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..b0f249f
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,47 @@
+================
+Intervaltree-Bio
+================
+
+Convenience classes for loading UCSC genomic annotation records into a set of `interval tree <https://pypi.python.org/pypi/intervaltree>`__ data structures.
+
+Installation
+------------
+
+The easiest way to install most Python packages is via ``easy_install`` or ``pip``::
+
+ $ pip install intervaltree-bio
+
+The package requires the ``intervaltree`` package (which is normally installed automatically when using ``pip`` or ``easy_install``).
+
+Usage
+--------
+
+One of the major uses for Interval tree data structures is in bioinformatics, where the
+intervals correspond to genes or other features of the genome.
+
+As genomes typically consist of a set of *chromosomes*, a separate interval tree for each
+chromosome has to be maintained. Thus, rather than using an single interval tree, you would typically use
+something like ``defaultdict(IntervalTree)`` to index data of genomic features.
+The module ``intervaltree_bio`` offers a ``GenomeIntervalTree`` data structure, which is a similar convenience
+data structure. In addition to specific methods for working with genomic intervals it also
+provides facilities for reading BED files and the refGene table from `UCSC <http://genome.ucsc.edu/>`__.
+
+The core example is loading the transcription regions of the ``knownGene`` table from the UCSC website::
+
+ >> from intervaltree_bio import GenomeIntervalTree
+ >> knownGene = GenomeIntervalTree.from_table()
+ >> len(knownGene)
+
+It is then possible to use the data structure to search known genes within given intervals::
+
+ >> result = knownGene[b'chr1'].search(100000, 138529)
+
+It is possible to load other UCSC tables besides ``knownGene`` or specify custom URL or file to read the table from.
+Consult the docstring of the ``GenomeIntervalTree.from_table`` method for more details.
+
+Copyright
+----------
+
+ * Copyright (c) Konstantin Tretyakov
+ * MIT license.
+ * Report issues via `Github <https://github.com/konstantint/intervaltree-bio>`__.
diff --git a/intervaltree_bio/__init__.py b/intervaltree_bio/__init__.py
new file mode 100644
index 0000000..083baca
--- /dev/null
+++ b/intervaltree_bio/__init__.py
@@ -0,0 +1,230 @@
+'''
+intervaltree-bio: Interval tree convenience classes for genomic data.
+
+One of the major uses for Interval tree data structures is in bioinformatics, where the
+intervals correspond to genes or other features of the genome.
+
+As genomes typically consist of a set of *chromosomes*, a separate interval tree for each
+chromosome has to be maintained. Thus, rather than using an IntervalTree, you would typically use
+something like ``defaultdict(IntervalTree)`` to index data of genomic features.
+This module offers a ``GenomeIntervalTree`` data structure, which is a similar convenience
+data structure. In addition to specific methods for working with genomic intervals it also
+provides facilities for reading BED files and the refGene table from UCSC.
+
+Copyright 2014, Konstantin Tretyakov
+
+Licensed under MIT.
+'''
+try:
+ from urllib import urlopen
+ from StringIO import StringIO as BytesIO
+except ImportError: # Python 3?
+ from urllib.request import urlopen
+ from io import BytesIO
+
+import zlib
+import warnings
+from collections import defaultdict
+from intervaltree import Interval, IntervalTree
+
+class UCSCTable(object):
+ '''A container class for the parsing functions, used in GenomeIntervalTree.from_table``.'''
+
+ KNOWN_GENE_FIELDS = ['name', 'chrom', 'strand', 'txStart', 'txEnd', 'cdsStart', 'cdsEnd', 'exonCount', 'exonStarts', 'exonEnds', 'proteinID', 'alignID']
+ REF_GENE_FIELDS = ['bin', 'name', 'chrom', 'strand', 'txStart', 'txEnd', 'cdsStart', 'cdsEnd', 'exonCount', 'exonStarts', 'exonEnds', 'score', 'name2', 'cdsStartStat', 'cdsEndStat', 'exonFrames']
+ ENS_GENE_FIELDS = REF_GENE_FIELDS
+
+ @staticmethod
+ def KNOWN_GENE(line):
+ return dict(zip(UCSCTable.KNOWN_GENE_FIELDS, line.split(b'\t')))
+ @staticmethod
+ def REF_GENE(line):
+ return dict(zip(UCSCTable.REF_GENE_FIELDS, line.split(b'\t')))
+ @staticmethod
+ def ENS_GENE(line):
+ return dict(zip(UCSCTable.ENS_GENE_FIELDS, line.split(b'\t')))
+
+class IntervalMakers(object):
+ '''A container class for interval-making functions, used in GenomeIntervalTree.from_table and GenomeIntervalTree.from_bed.'''
+
+ @staticmethod
+ def TX(d):
+ return [Interval(int(d['txStart']), int(d['txEnd']), d)]
+
+ @staticmethod
+ def CDS(d):
+ return [Interval(int(d['cdsStart']), int(d['cdsEnd']), d)]
+
+ @staticmethod
+ def EXONS(d):
+ exStarts = d['exonStarts'].split(b',')
+ exEnds = d['exonEnds'].split(b',')
+ for i in range(int(d['exonCount'])):
+ yield Interval(int(exStarts[i]), int(exEnds[i]), d)
+
+def _fix(interval):
+ '''
+ Helper function for ``GenomeIntervalTree.from_bed and ``.from_table``.
+
+ Data tables may contain intervals with begin >= end. Such intervals lead to infinite recursions and
+ other unpleasant behaviour, so something has to be done about them. We 'fix' them by simply setting end = begin+1.
+ '''
+ if interval.begin >= interval.end:
+ warnings.warn("Interval with reversed coordinates (begin >= end) detected when reading data. Interval was automatically fixed to point interval [begin, begin+1).")
+ return Interval(interval.begin, interval.begin+1, interval.data)
+ else:
+ return interval
+
+class GenomeIntervalTree(defaultdict):
+ '''
+ The data structure maintains a set of IntervalTrees, one for each chromosome.
+ It is essentially a ``defaultdict(IntervalTree)`` with a couple of convenience methods
+ for reading various data formats.
+
+ Examples::
+
+ >>> gtree = GenomeIntervalTree()
+ >>> gtree.addi('chr1', 0, 100)
+ >>> gtree.addi('chr1', 1, 100)
+ >>> gtree.addi('chr2', 0, 100)
+ >>> len(gtree)
+ 3
+ >>> len(gtree['chr1'])
+ 2
+ >>> sorted(gtree.keys())
+ ['chr1', 'chr2']
+
+ '''
+ def __init__(self):
+ super(GenomeIntervalTree, self).__init__(IntervalTree)
+
+ def addi(self, chrom, begin, end, data=None):
+ self[chrom].addi(begin, end, data)
+
+ def __len__(self):
+ return sum([len(tree) for tree in self.values()])
+
+ @staticmethod
+ def from_bed(fileobj, field_sep=b'\t', interval_maker=None):
+ '''
+ Initialize a ``GenomeIntervalTree`` from a BED file.
+ Each line of the file must consist of several fields, separated using ``field_sep``.
+ The first three fields are ``chrom``, ``start`` and ``end`` (where ``start`` is 0-based and
+ the corresponding interval is ``[start, end)``). The remaining fields are ``name``, ``score``,
+ ``strand``, ..., or something else, depending on the flavor of the format.
+
+ Each Interval in the tree has its data field set to a list with "remaining" fields,
+ i.e. interval.data[0] should be the ``name``, interval.data[1] is the ``score``, etc.
+
+ if the ``interval_maker`` parameter is not None, intervals are created by calling this function with the BED line split into fields as input.
+ The function must return an iterable of ``Interval`` objects.
+
+ Example::
+ >>> test_url = 'http://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/wgEncodeAwgTfbsUniform/wgEncodeAwgTfbsBroadDnd41Ezh239875UniPk.narrowPeak.gz'
+ >>> data = zlib.decompress(urlopen(test_url).read(), 16+zlib.MAX_WBITS)
+ >>> gtree = GenomeIntervalTree.from_bed(BytesIO(data))
+ >>> len(gtree)
+ 1732
+ >>> assert gtree[b'chr10'].search(22610878) == set([Interval(22610878, 22611813, [b'.', b'1000', b'.', b'471.725544438908', b'-1', b'3.21510858105313', b'389']), Interval(22610878, 22611813, [b'.', b'791', b'.', b'123.885507169449', b'-1', b'3.21510858105313', b'596'])])
+ >>> assert gtree[b'chr10'].search(22611813) == set([])
+ >>> assert gtree[b'chr1'].search(145036590, 145036594) == set([Interval(145036593, 145037123, [b'.', b'247', b'.', b'38.6720804428054', b'-1', b'3.06233123683911', b'265'])])
+ >>> assert gtree[b'chr10'].search(145036594, 145036595) == set([])
+
+ '''
+ # We collect all intervals into a set of lists, and then put them all at once into the tree structures
+ # It is slightly more efficient than adding intervals one by one.
+ # Moreover, the current implementation throws a "maximum recursion depth exceeded" error
+ # in this case on large files (TODO)
+
+ interval_lists = defaultdict(list)
+ for ln in fileobj:
+ if ln.endswith(b'\n'):
+ ln = ln[0:-1]
+ ln = ln.split(field_sep)
+ if interval_maker is not None:
+ for interval in interval_maker(ln):
+ interval_lists[ln[0]].append(_fix(interval))
+ else:
+ interval_lists[ln[0]].append(_fix(Interval(int(ln[1]), int(ln[2]), data=ln[3:])))
+ gtree = GenomeIntervalTree()
+ for k, v in getattr(interval_lists, 'iteritems', interval_lists.items)():
+ gtree[k] = IntervalTree(v)
+ return gtree
+
+ @staticmethod
+ def from_table(fileobj=None, url='http://hgdownload.cse.ucsc.edu/goldenpath/hg19/database/knownGene.txt.gz',
+ parser=UCSCTable.KNOWN_GENE, mode='tx', decompress=None):
+ '''
+ UCSC Genome project provides several tables with gene coordinates (https://genome.ucsc.edu/cgi-bin/hgTables),
+ such as knownGene, refGene, ensGene, wgEncodeGencodeBasicV19, etc.
+ Indexing the rows of those tables into a ``GenomeIntervalTree`` is a common task, implemented in this method.
+
+ The table can be either specified as a ``fileobj`` (in which case the data is read line by line),
+ or via an ``url`` (the ``url`` may be to a ``txt`` or ``txt.gz`` file either online or locally).
+ The type of the table is specified using the ``parser`` parameter. This is a function that takes a line
+ of the file (with no line ending) and returns a dictionary, mapping field names to values. This dictionary will be assigned
+ to the ``data`` field of each interval in the resulting tree.
+
+ Finally, there are different ways genes can be mapped into intervals for the sake of indexing as an interval tree.
+ One way is to represent each gene via its transcribed region (``txStart``..``txEnd``). Another is to represent using
+ coding region (``cdsStart``..``cdsEnd``). Finally, the third possibility is to map each gene into several intervals,
+ corresponding to its exons (``exonStarts``..``exonEnds``).
+
+ The mode, in which genes are mapped to intervals is specified via the ``mode`` parameter. The value can be ``tx``, ``cds`` and
+ ``exons``, corresponding to the three mentioned possiblities.
+
+ If a more specific way of interval-mapping is required (e.g. you might want to create 'coding-region+-10k' intervals), you can provide
+ an "interval-maker" function as the ``mode`` parameter. An interval-maker function takes as input a dictionary, returned by the parser,
+ and returns an iterable of Interval objects.
+
+ The ``parser`` function must ensure that its output contains the field named ``chrom``, and also fields named ``txStart``/``txEnd`` if ``mode=='tx'``,
+ fields ``cdsStart``/``cdsEnd`` if ``mode=='cds'``, and fields ``exonCount``/``exonStarts``/``exonEnds`` if ``mode=='exons'``.
+
+ The ``decompress`` parameter specifies whether the provided file is gzip-compressed.
+ This only applies to the situation when the url is given (no decompression is made if fileobj is provided in any case).
+ If decompress is None, data is decompressed if the url ends with .gz, otherwise decompress = True forces decompression.
+
+ >> knownGene = GenomeIntervalTree.from_table()
+ >> len(knownGene)
+ 82960
+ >> result = knownGene[b'chr1'].search(100000, 138529)
+ >> len(result)
+ 1
+ >> list(result)[0].data['name']
+ b'uc021oeg.2'
+ '''
+ if fileobj is None:
+ data = urlopen(url).read()
+ if (decompress is None and url.endswith('.gz')) or decompress:
+ data = zlib.decompress(data, 16+zlib.MAX_WBITS)
+ fileobj = BytesIO(data)
+
+ interval_lists = defaultdict(list)
+
+ if mode == 'tx':
+ interval_maker = IntervalMakers.TX
+ elif mode == 'cds':
+ interval_maker = IntervalMakers.CDS
+ elif mode == 'exons':
+ interval_maker = IntervalMakers.EXONS
+ elif getattr(mode, __call__, None) is None:
+ raise Exception("Parameter `mode` may only be 'tx', 'cds', 'exons' or a callable")
+ else:
+ interval_maker = mode
+
+ for ln in fileobj:
+ if ln.endswith(b'\n'):
+ ln = ln[0:-1]
+ d = parser(ln)
+ for interval in interval_maker(d):
+ interval_lists[d['chrom']].append(_fix(interval))
+
+ # Now convert interval lists into trees
+ gtree = GenomeIntervalTree()
+ for chrom, lst in getattr(interval_lists, 'iteritems', interval_lists.items)():
+ gtree[chrom] = IntervalTree(lst)
+ return gtree
+
+ def __reduce__(self):
+ t = defaultdict.__reduce__(self)
+ return (t[0], ()) + t[2:]
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..d336f54
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,9 @@
+[egg_info]
+tag_build =
+tag_svn_revision = false
+
+[pytest]
+addopts = --ignore=setup.py --ignore=build --ignore=dist --doctest-modules
+norecursedirs=*.egg
+
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..1aeef19
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,54 @@
+'''
+intervaltree-bio: Interval tree convenience classes for genomic data.
+
+Note that "python setup.py test" invokes pytest on the package. With appropriately
+configured setup.cfg, this will check both xxx_test modules and docstrings.
+
+Copyright 2014, Konstantin Tretyakov.
+
+Licensed under MIT.
+'''
+import sys
+from setuptools import setup, find_packages
+from setuptools.command.test import test as TestCommand
+
+# This is a plug-in for setuptools that will invoke py.test
+# when you run python setup.py test
+class PyTest(TestCommand):
+ def finalize_options(self):
+ TestCommand.finalize_options(self)
+ self.test_args = []
+ self.test_suite = True
+
+ def run_tests(self):
+ import pytest # import here, because outside the required eggs aren't loaded yet
+ sys.exit(pytest.main(self.test_args))
+
+
+version = '1.0.1'
+setup(
+ name = 'intervaltree_bio',
+ version = version,
+ description = 'Interval tree convenience classes for genomic data',
+ long_description=open("README.rst").read(),
+ classifiers=[ # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+ 'Development Status :: 4 - Beta',
+ 'Programming Language :: Python',
+ 'Intended Audience :: Science/Research',
+ 'License :: OSI Approved :: MIT License',
+ 'Topic :: Scientific/Engineering :: Bio-Informatics',
+ 'Topic :: Software Development :: Libraries',
+ ],
+ keywords="interval-tree data-structure intervals tree genomics bioinformatics ucsc", # Separate with spaces
+ author = 'Konstantin Tretyakov',
+ author_email = 'kt at ut.ee',
+ url='https://github.com/konstantint/intervaltree-bio',
+ license="MIT",
+ packages=find_packages(exclude=['examples', 'tests']),
+ include_package_data=True,
+ zip_safe=True,
+ install_requires=['intervaltree'],
+ tests_require=['pytest'],
+ cmdclass={'test': PyTest},
+ entry_points={}
+)
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..99b7f2f
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,10 @@
+'''
+intervaltree-bio: Interval tree convenience classes for genomic data.
+
+Test module. Meant for use with ``py.test``.
+To run all tests simply invoke ``python setup.py test`` from the package root.
+
+Copyright 2014 Konstantin Tretyakov
+
+Licensed under MIT.
+'''
diff --git a/tests/genomeintervaltree_test.py b/tests/genomeintervaltree_test.py
new file mode 100644
index 0000000..9b5bff5
--- /dev/null
+++ b/tests/genomeintervaltree_test.py
@@ -0,0 +1,54 @@
+'''
+Test module for GenomeIntervalTree
+
+Copyright 2014, Konstantin Tretyakov
+
+Licensed under MIT license.
+'''
+import os
+try:
+ from urllib import urlretrieve
+except ImportError: # Python 3?
+ from urllib.request import urlretrieve
+
+from intervaltree_bio import GenomeIntervalTree, UCSCTable
+
+def test_knownGene():
+ # To speed up testing, we'll download the file and reuse the downloaded copy
+ knownGene_url = 'http://hgdownload.cse.ucsc.edu/goldenpath/hg19/database/knownGene.txt.gz'
+ # Mirror. Slightly faster and more stable, I believe:
+ knownGene_url = 'http://kt.era.ee/distribute/pyintervaltree/knownGene.txt.gz'
+
+ # To speed up testing, we'll download the file and reuse the downloaded copy
+ knownGene_file, headers = urlretrieve(knownGene_url)
+
+ knownGene_localurl = 'file:///%s' % os.path.abspath(knownGene_file)
+ knownGene = GenomeIntervalTree.from_table(url=knownGene_localurl, decompress=True) # Py3 downloads .gz files to local files with names not ending with .gz
+ assert len(knownGene) == 82960
+ result = knownGene[b'chr1'].search(100000, 138529)
+ assert len(result) == 1
+ assert list(result)[0].data['name'] == b'uc021oeg.2'
+
+ knownGene = GenomeIntervalTree.from_table(url=knownGene_localurl, mode='cds', decompress=True)
+ assert len(knownGene) == 82960
+ assert not knownGene[b'chr1'].overlaps(100000, 138529)
+
+ knownGene = GenomeIntervalTree.from_table(url=knownGene_localurl, mode='exons', decompress=True)
+ assert len(knownGene) == 742493
+ result = list(knownGene[b'chr1'].search(134772, 140566))
+ assert len(result) == 3
+ assert result[0].data == result[1].data and result[0].data == result[2].data
+
+def test_ensGene():
+ # Smoke-test we can at least read ensGene.
+ ensGene_url = 'http://hgdownload.cse.ucsc.edu/goldenpath/hg19/database/ensGene.txt.gz'
+ ensGene_url = 'http://kt.era.ee/distribute/pyintervaltree/ensGene.txt.gz'
+ ensGene = GenomeIntervalTree.from_table(url=ensGene_url, mode='cds', parser=UCSCTable.ENS_GENE)
+ assert len(ensGene) == 204940
+
+def test_refGene():
+ # Smoke-test for refGene
+ refGene_url = 'http://hgdownload.cse.ucsc.edu/goldenpath/hg19/database/refGene.txt.gz'
+ refGene_url = 'http://kt.era.ee/distribute/pyintervaltree/refGene.txt.gz'
+ refGene = GenomeIntervalTree.from_table(url=refGene_url, mode='tx', parser=UCSCTable.REF_GENE)
+ assert len(refGene) == 52350 # NB: Some time ago it was 50919, hence it seems the table data changes on UCSC and eventually the mirror and UCSC won't be the same.
diff --git a/tests/pickle_test.py b/tests/pickle_test.py
new file mode 100644
index 0000000..9ba566e
--- /dev/null
+++ b/tests/pickle_test.py
@@ -0,0 +1,22 @@
+'''
+Test module for GenomeIntervalTree
+
+Copyright 2014, Konstantin Tretyakov
+
+Licensed under MIT license.
+'''
+import os
+
+from intervaltree_bio import GenomeIntervalTree
+from collections import defaultdict
+import pickle
+
+def test_pickling():
+ git = GenomeIntervalTree()
+ git['a'][1:2] = ['some', 'data']
+ git['a'][1.5:2.5] = ['more', 'data']
+ git['b'][10:12] = ['even', 'more', 'data']
+ s = pickle.dumps(git)
+ new_git = pickle.loads(s)
+ assert len(git) == len(new_git)
+ assert len(git['a']) == len(new_git['a'])
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-intervaltree-bio.git
More information about the debian-med-commit
mailing list