[med-svn] [tophat] 01/06: Imported Upstream version 2.1.1+dfsg
Alex Mestiashvili
malex-guest at moszumanska.debian.org
Thu Mar 17 13:47:28 UTC 2016
This is an automated email from the git hooks/post-receive script.
malex-guest pushed a commit to branch master
in repository tophat.
commit 5e1ff735e522336796365b85772461a113a253cb
Author: Alexandre Mestiashvili <alex at biotec.tu-dresden.de>
Date: Thu Mar 17 14:22:48 2016 +0100
Imported Upstream version 2.1.1+dfsg
---
AUTHORS | 10 +
COPYING | 113 ---
Makefile.am | 2 +-
Makefile.in | 6 +-
ax_boost_thread.m4 | 17 +-
configure | 51 +-
configure.ac | 8 +-
src/GBase.cpp | 65 +-
src/GBase.h | 15 +-
src/GStr.cpp | 20 +-
src/GVec.hh | 40 +-
src/Makefile.am | 1115 +++++++++++++-----------
src/Makefile.in | 1139 ++++++++++++------------
src/bam2fastx.cpp | 160 ++--
src/bam_merge.h | 3 +
src/common.cpp | 4 +-
src/common.h | 4 +-
src/gff.cpp | 254 +++---
src/gff.h | 23 +-
src/intervaltree/__init__.py | 22 +
src/intervaltree/interval.py | 302 +++++++
src/intervaltree/intervaltree.py | 947 ++++++++++++++++++++
src/intervaltree/node.py | 593 +++++++++++++
src/long_spanning_reads.cpp | 4 +-
src/map2gtf.cpp | 13 -
src/reads.h | 10 +-
src/segment_juncs.cpp | 132 ++-
src/sortedcontainers/__init__.py | 55 ++
src/sortedcontainers/sorteddict.py | 737 ++++++++++++++++
src/sortedcontainers/sortedlist.py | 1233 ++++++++++++++++++++++++++
src/sortedcontainers/sortedlistwithkey.py | 1331 +++++++++++++++++++++++++++++
src/sortedcontainers/sortedset.py | 294 +++++++
src/tophat-fusion-post | 2 +-
src/tophat.py | 16 +-
src/tophat2.in | 15 -
src/tophat2.sh | 10 +
src/tophat_reports.cpp | 27 +-
37 files changed, 7255 insertions(+), 1537 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 5b5292e..7307eef 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,8 +17,18 @@ The SeqAn-1.3 library is used in TopHat and some of its sources are included
in TopHat source releases; its authors are Andreas Doring, David Weese,
Tobias Rausch, and Knut Reinert.
+The IntervalTree library is used by TopHat in its fusion-calling pipeline;
+ its authors are Chaim-Leib Halbert and Konstantin Tretyakov. This package
+ is released under the Apache 2.0 license.
+
+The SortedContainers library is used by TopHat in its fusion-calling
+ pipeline; its author is Grant Jenks. This package is released under the
+ Apache 2.0 license.
+
Websites:
TopHat: http://ccb.jhu.edu/software/tophat
Bowtie: http://bowtie-bio.sourceforge.net/bowtie2
Samtools: http://samtools.sourceforge.net
SeqAn: http://www.seqan.de
+ IntervalTree: https://github.com/chaimleib/intervaltree
+ SortedContainers: http://www.grantjenks.com/docs/sortedcontainers/
diff --git a/COPYING b/COPYING
deleted file mode 100644
index 31a6350..0000000
--- a/COPYING
+++ /dev/null
@@ -1,113 +0,0 @@
-The Artistic License
-
-Preamble
-
-The intent of this document is to state the conditions under which a
-Package may be copied, such that the Copyright Holder maintains some
-semblance of artistic control over the development of the package,
-while giving the users of the package the right to use and distribute
-the Package in a more-or-less customary fashion, plus the right to
-make reasonable modifications.
-
-Definitions:
- * "Package" refers to the collection of files distributed by the
- Copyright Holder, and derivatives of that collection of files
- created through textual modification.
- * "Standard Version" refers to such a Package if it has not been
- modified, or has been modified in accordance with the wishes of
- the Copyright Holder.
- * "Copyright Holder" is whoever is named in the copyright or
- copyrights for the package.
- * "You" is you, if you're thinking about copying or distributing
- this Package.
- * "Reasonable copying fee" is whatever you can justify on the
- basis of media cost, duplication charges, time of people
- involved, and so on. (You will not be required to justify it to
- the Copyright Holder, but only to the computing community at
- large as a market that must bear the fee.)
- * "Freely Available" means that no fee is charged for the item
- itself, though there may be fees involved in handling the
- item. It also means that recipients of the item may redistribute
- it under the same conditions they received it.
-
-1. You may make and give away verbatim copies of the source form of
- the Standard Version of this Package without restriction, provided
- that you duplicate all of the original copyright notices and
- associated disclaimers.
-
-2. You may apply bug fixes, portability fixes and other modifications
- derived from the Public Domain or from the Copyright Holder. A
- Package modified in such a way shall still be considered the
- Standard Version.
-
-3. You may otherwise modify your copy of this Package in any way,
- provided that you insert a prominent notice in each changed file
- stating how and when you changed that file, and provided that you
- do at least ONE of the following:
-
- a) place your modifications in the Public Domain or otherwise make
- them Freely Available, such as by posting said modifications to
- Usenet or an equivalent medium, or placing the modifications on a
- major archive site such as ftp.uu.net, or by allowing the
- Copyright Holder to include your modifications in the Standard
- Version of the Package.
-
- b) use the modified Package only within your corporation or
- organization.
-
- c) rename any non-standard executables so the names do not
- conflict with standard executables, which must also be provided,
- and provide a separate manual page for each non-standard
- executable that clearly documents how it differs from the Standard
- Version.
-
- d) make other distribution arrangements with the Copyright Holder.
-
-4. You may distribute the programs of this Package in object code or
- executable form, provided that you do at least ONE of the
- following:
-
- a) distribute a Standard Version of the executables and library
- files, together with instructions (in the manual page or
- equivalent) on where to get the Standard Version.
-
- b) accompany the distribution with the machine-readable source of
- the Package with your modifications.
-
- c) accompany any non-standard executables with their corresponding
- Standard Version executables, giving the non-standard executables
- non-standard names, and clearly documenting the differences in
- manual pages (or equivalent), together with instructions on where
- to get the Standard Version.
-
- d) make other distribution arrangements with the Copyright Holder.
-
-5. You may charge a reasonable copying fee for any distribution of
- this Package. You may charge any fee you choose for support of this
- Package. You may not charge a fee for this Package itself. However,
- you may distribute this Package in aggregate with other (possibly
- commercial) programs as part of a larger (possibly commercial)
- software distribution provided that you do not advertise this
- Package as a product of your own.
-
-6. The scripts and library files supplied as input to or produced as
- output from the programs of this Package do not automatically fall
- under the copyright of this Package, but belong to whomever
- generated them, and may be sold commercially, and may be aggregated
- with this Package.
-
-7. C or perl subroutines supplied by you and linked into this Package
- shall not be considered part of this Package.
-
-8. The name of the Copyright Holder may not be used to endorse or
- promote products derived from this software without specific prior
- written permission.
-
-9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
- OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-The End
-This license is approved by the Open Source Initiative
-(www.opensource.org) for certifying software as OSI Certified Open
-Source.
diff --git a/Makefile.am b/Makefile.am
index a319a05..cd9ae7e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,6 @@ ALWAYS_BUILT = src
SUBDIRS = $(ALWAYS_BUILT)
DIST_SUBDIRS = $(ALWAYS_BUILT)
-EXTRA_DIST = LICENSE
+EXTRA_DIST = LICENSE README AUTHORS
.PHONY: FORCE
diff --git a/Makefile.in b/Makefile.in
index 067e05d..0711a15 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -52,8 +52,8 @@ host_triplet = @host@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
- $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
- THANKS ar-lib config.guess config.sub install-sh missing
+ $(top_srcdir)/configure AUTHORS ChangeLog INSTALL NEWS THANKS \
+ ar-lib config.guess config.sub depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_boost_base.m4 \
$(top_srcdir)/ax_boost_thread.m4 $(top_srcdir)/configure.ac
@@ -248,7 +248,7 @@ top_srcdir = @top_srcdir@
ALWAYS_BUILT = src
SUBDIRS = $(ALWAYS_BUILT)
DIST_SUBDIRS = $(ALWAYS_BUILT)
-EXTRA_DIST = LICENSE
+EXTRA_DIST = LICENSE README AUTHORS
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
diff --git a/ax_boost_thread.m4 b/ax_boost_thread.m4
index 30cc340..d07fd9c 100644
--- a/ax_boost_thread.m4
+++ b/ax_boost_thread.m4
@@ -68,12 +68,12 @@ if test "$ax_cv_boost_thread" = yes; then
AC_CHECK_LIB($ax_lib, main, [BOOST_THREAD_LIBS=-l$ax_lib; break])
done
- # in recent Boost versions, boost::thread depends on boost::system
+ # in some Boost versions, boost::thread depends on boost::system
AC_CACHE_CHECK(whether Boost::Thread needs Boost::System library,
ax_cv_boost_thread_system,
[LIBS="$LIBS $BOOST_THREAD_LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
- [[boost::thread_group thrds; return 0;]])],
+ [[boost::thread_group thrds; return 0;]])],
[ax_cv_boost_thread_system=no],
[LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
AC_LINK_IFELSE([
@@ -82,8 +82,17 @@ if test "$ax_cv_boost_thread" = yes; then
],
[BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
ax_cv_boost_thread_system=yes],
- [AC_ERROR([Cannot use Boost::Thread])]
- )])
+ [LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds; return 0;]])
+ ],
+ [BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+ ax_cv_boost_thread_system=yes],
+ [AC_ERROR([Cannot use Boost::Thread])]
+ )
+ ])
+ ])
])
CXXFLAGS=$CXXFLAGS_SAVE
diff --git a/configure b/configure
index 8bdcd01..e1424ff 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tophat 2.1.0.
+# Generated by GNU Autoconf 2.69 for tophat 2.1.1.
#
# Report bugs to <tophat.cufflinks at gmail.com>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='tophat'
PACKAGE_TARNAME='tophat'
-PACKAGE_VERSION='2.1.0'
-PACKAGE_STRING='tophat 2.1.0'
+PACKAGE_VERSION='2.1.1'
+PACKAGE_STRING='tophat 2.1.1'
PACKAGE_BUGREPORT='tophat.cufflinks at gmail.com'
PACKAGE_URL=''
@@ -1304,7 +1304,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures tophat 2.1.0 to adapt to many kinds of systems.
+\`configure' configures tophat 2.1.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1374,7 +1374,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tophat 2.1.0:";;
+ short | recursive ) echo "Configuration of tophat 2.1.1:";;
esac
cat <<\_ACEOF
@@ -1484,7 +1484,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tophat configure 2.1.0
+tophat configure 2.1.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1945,7 +1945,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by tophat $as_me 2.1.0, which was
+It was created by tophat $as_me 2.1.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2294,7 +2294,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-$as_echo "#define SVN_REVISION \"exported\"" >>confdefs.h
+$as_echo "#define SVN_REVISION \"ecf7617\"" >>confdefs.h
@@ -2777,7 +2777,7 @@ fi
# Define the identity of the package.
PACKAGE='tophat'
- VERSION='2.1.0'
+ VERSION='2.1.1'
cat >>confdefs.h <<_ACEOF
@@ -5602,7 +5602,7 @@ fi
done
- # in recent Boost versions, boost::thread depends on boost::system
+ # in some Boost versions, boost::thread depends on boost::system
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Boost::Thread needs Boost::System library" >&5
$as_echo_n "checking whether Boost::Thread needs Boost::System library... " >&6; }
if ${ax_cv_boost_thread_system+:} false; then :
@@ -5641,11 +5641,34 @@ if ac_fn_cxx_try_link "$LINENO"; then :
BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
ax_cv_boost_thread_system=yes
else
+ LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <boost/thread/thread.hpp>
+int
+main ()
+{
+boost::thread_group thrds; return 0;
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+ ax_cv_boost_thread_system=yes
+else
as_fn_error $? "Cannot use Boost::Thread" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
@@ -6900,7 +6923,7 @@ fi
CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
CXXFLAGS="$CFLAGS"
-CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.3"
+CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.4.2"
LDFLAGS="$BAM_LDFLAGS $BOOST_LDFLAGS $user_LDFLAGS"
if test "`cd $srcdir && pwd`" != "`pwd`"; then
@@ -6925,7 +6948,7 @@ fi
# Define the identity of the package.
PACKAGE='tophat'
- VERSION='2.1.0'
+ VERSION='2.1.1'
cat >>confdefs.h <<_ACEOF
@@ -7868,7 +7891,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by tophat $as_me 2.1.0, which was
+This file was extended by tophat $as_me 2.1.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7934,7 +7957,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-tophat config.status 2.1.0
+tophat config.status 2.1.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 00a673c..dd5ac83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
-define([svnversion], esyscmd([sh -c "svnversion|tr -d '\n'"]))dnl
-AC_INIT([tophat],[2.1.0],[tophat.cufflinks at gmail.com])
-AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision])
+define([gitversion], esyscmd([sh -c 'git show -s --pretty=format:%h']))dnl
+AC_INIT([tophat],[2.1.1],[tophat.cufflinks at gmail.com])
+AC_DEFINE(SVN_REVISION, "gitversion", [SVN Revision])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
@@ -105,7 +105,7 @@ AS_IF([test "x$enable_debug" = xyes],
CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
CXXFLAGS="$CFLAGS"
-CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.3"
+CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.4.2"
LDFLAGS="$BAM_LDFLAGS $BOOST_LDFLAGS $user_LDFLAGS"
AM_INIT_AUTOMAKE([-Wall foreign tar-pax foreign])
diff --git a/src/GBase.cpp b/src/GBase.cpp
index 4671e42..afb0791 100644
--- a/src/GBase.cpp
+++ b/src/GBase.cpp
@@ -1,6 +1,7 @@
#include "GBase.h"
#include <stdarg.h>
#include <ctype.h>
+#include <errno.h>
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
@@ -188,22 +189,38 @@ int Gstrcmp(const char* a, const char* b, int n) {
}
-int G_mkdir(const char* path, int perms=0775) {
+int G_mkdir(const char* path, int perms = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
+ //int perms=(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
#ifdef __WIN32__
return _mkdir(path);
#else
- //#if _POSIX_C_SOURCE
- // return ::mkdir(path);
- //#else
- return mkdir(path, perms); // not sure if this works on mac
- //#endif
+ return mkdir(path, perms);
#endif
}
+void Gmktempdir(char* templ) {
+#ifdef __WIN32__
+ int blen=strlen(templ);
+ if (_mktemp_s(templ, blen)!=0)
+ GError("Error creating temp dir %s!\n", templ);
+#else
+ char* cdir=mkdtemp(templ);
+ if (cdir==NULL)
+ GError("Error creating temp dir %s!(%s)\n", templ, strerror(errno));
+#endif
+}
+
int Gmkdir(const char *path, bool recursive, int perms) {
if (path==NULL || path[0]==0) return -1;
- if (!recursive) return G_mkdir(path, perms);
+ mode_t process_mask = umask(0); //is this really needed?
+ if (!recursive) {
+ int r=G_mkdir(path, perms);
+ if (r!=0)
+ GMessage("Warning: G_mkdir(%s) failed: %s\n", path, strerror(errno));
+ umask(process_mask);
+ return r;
+ }
int plen=strlen(path);
char* gpath=NULL;
//make sure gpath ends with /
@@ -221,17 +238,35 @@ int Gmkdir(const char *path, bool recursive, int perms) {
while (*ss!=0 && (psep=strchr(ss, '/'))!=NULL) {
*psep=0; //now gpath is the path up to this /
ss=psep; ++ss; //ss repositioned just after the /
- // create current level
- if (fileExists(gpath)!=1 && G_mkdir(gpath, perms)!=0) {
+ // create current level if it doesn't exist
+ if (fileExists(gpath)) { //path exists
+ *psep='/';
+ continue; //assume it's a directory or a symlink to one
+ //if not, it'll fail later
+ }
+ int mkdir_err=0;
+ if ((mkdir_err=G_mkdir(gpath, perms))!=0) {
+ GMessage("Warning: mkdir(%s) failed: %s\n", gpath, strerror(errno));
GFREE(gpath);
+ umask(process_mask);
return -1;
}
*psep='/';
}
GFREE(gpath);
+ umask(process_mask);
return 0;
}
+FILE* Gfopen(const char *path, char *mode) {
+ FILE* f=NULL;
+ if (mode==NULL) f=fopen(path, "rb");
+ else f=fopen(path, mode);
+ if (f==NULL)
+ GMessage("Error opening file '%s': %s\n", path, strerror(errno));
+ return f;
+}
+
bool GstrEq(const char* a, const char* b) {
if (a==NULL || b==NULL) return false;
register int i=0;
@@ -674,12 +709,12 @@ const char* getFileExt(const char* filepath) {
int fileExists(const char* fname) {
struct stat stFileInfo;
int r=0;
- // Attempt to get the file attributes
+ // Attempt to get the path attributes
int fs = stat(fname,&stFileInfo);
if (fs == 0) {
r=3;
// We were able to get the file attributes
- // so the file obviously exists.
+ // so the path exists
if (S_ISREG (stFileInfo.st_mode)) {
r=2;
}
@@ -690,14 +725,6 @@ int fileExists(const char* fname) {
return r;
}
-/*bool fileExists(const char* filepath) {
- if (filepath==NULL) return false;
- FILE* ft=fopen(filepath, "rb");
- if (ft==NULL) return false;
- fclose(ft);
- return true;
-}
-*/
int64 fileSize(const char* fpath) {
struct stat results;
if (stat(fpath, &results) == 0)
diff --git a/src/GBase.h b/src/GBase.h
index ec50000..8ff89f3 100644
--- a/src/GBase.h
+++ b/src/GBase.h
@@ -1,9 +1,9 @@
#ifndef G_BASE_DEFINED
#define G_BASE_DEFINED
-#ifndef _POSIX_SOURCE
+//#ifndef _POSIX_SOURCE
//mostly for MinGW
-#define _POSIX_SOURCE
-#endif
+//#define _POSIX_SOURCE
+//#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -171,8 +171,8 @@ inline int iround(double x) {
return (int)floor(x + 0.5);
}
-int Gmkdir(const char *path, bool recursive=true, int perms=0775);
-
+int Gmkdir(const char *path, bool recursive=true, int perms = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));
+void Gmktempdir(char* templ);
/****************************************************************************/
@@ -240,6 +240,9 @@ char* strupper(char * str);
void* Gmemscan(void *mem, unsigned int len,
void *part, unsigned int partlen);
+
+FILE* Gfopen(const char *path, char *mode=NULL);
+
// test if a char is in a string:
bool chrInStr(char c, const char* str);
@@ -441,7 +444,7 @@ const char* getFileExt(const char* filepath);
int fileExists(const char* fname);
-//returns 0 if file entry doesn't exist
+//returns 0 if path doesn't exist
// 1 if it's a directory
// 2 if it's a regular file
// 3 otherwise (?)
diff --git a/src/GStr.cpp b/src/GStr.cpp
index 20137af..f4e6784 100644
--- a/src/GStr.cpp
+++ b/src/GStr.cpp
@@ -679,17 +679,23 @@ GStr GStr::substr(int idx, int len) const {
// A negative idx specifies an idx from the right of the string.
if (idx < 0)
idx += length();
-
- // A length of -1 specifies the rest of the string.
- if (len < 0 || len>length()-idx)
+ else if (idx>=length()) {
+ len=0;
+ idx=length();
+ }
+ if (len) {
+ // A length of -1 specifies the rest of the string.
+ if (len < 0 || len>length()-idx)
len = length() - idx;
-
- if (idx<0 || idx>=length() || len<0 )
+ if (idx<0 || idx>=length() || len<0 )
invalid_args_error("substr()");
+ }
GStr newstring;
- newstring.replace_data(len);
- ::memcpy(newstring.chrs(), &chars()[idx], len);
+ if (len) {
+ newstring.replace_data(len);
+ ::memcpy(newstring.chrs(), &chars()[idx], len);
+ }
return newstring;
}
diff --git a/src/GVec.hh b/src/GVec.hh
index 7b9800b..7023b75 100644
--- a/src/GVec.hh
+++ b/src/GVec.hh
@@ -566,38 +566,38 @@ template <class OBJ> GPVec<OBJ>::GPVec(GPVec& list) { //copy constructor
fCount=list.fCount;
fCapacity=list.fCapacity;
fList=NULL;
- if (fCapacity>0) {
- GMALLOC(fList, fCapacity*sizeof(OBJ*));
- }
fFreeProc=list.fFreeProc;
fCount=list.fCount;
- memcpy(fList, list.fList, fCount*sizeof(OBJ*));
- //for (int i=0;i<list.Count();i++) Add(list[i]);
+ if (fCapacity>0) {
+ GMALLOC(fList, fCapacity*sizeof(OBJ*));
+ memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+ }
}
template <class OBJ> GPVec<OBJ>::GPVec(GPVec* plist) { //another copy constructor
- fCount=0;
- fCapacity=plist->fCapacity;
- fList=NULL;
- if (fCapacity>0) {
- GMALLOC(fList, fCapacity*sizeof(OBJ*));
- }
- fFreeProc=plist->fFreeProc;
- fCount=plist->fCount;
- memcpy(fList, plist->fList, fCount*sizeof(OBJ*));
- //for (int i=0;i<list->fCount;i++) Add(plist->Get(i));
+ fCount=0;
+ fCapacity=plist->fCapacity;
+ fList=NULL;
+ fFreeProc=plist->fFreeProc;
+ fCount=plist->fCount;
+ if (fCapacity>0) {
+ GMALLOC(fList, fCapacity*sizeof(OBJ*));
+ memcpy(fList, plist->fList, fCount*sizeof(OBJ*));
+ }
}
template <class OBJ> const GPVec<OBJ>& GPVec<OBJ>::operator=(GPVec& list) {
if (&list!=this) {
Clear();
fFreeProc=list.fFreeProc;
- //Attention: the object *POINTERS* are copied,
- // but the actual object content is NOT duplicated
- //for (int i=0;i<list.Count();i++) Add(list[i]);
+ //Attention: only the *POINTERS* are copied,
+ // the actual objects are NOT duplicated
fCount=list.fCount;
- GMALLOC(fList, fCapacity*sizeof(OBJ*));
- memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+ fCapacity=list.fCapacity;
+ if (fCapacity>0) {
+ GMALLOC(fList, fCapacity*sizeof(OBJ*));
+ memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+ }
}
return *this;
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 54db7c6..551383f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,16 @@
# - and tophat2.in added
EXTRA_DIST = \
tophat.py \
-tophat2.in \
+tophat2.sh \
+intervaltree/__init__.py \
+intervaltree/interval.py \
+intervaltree/intervaltree.py \
+intervaltree/node.py \
+sortedcontainers/__init__.py \
+sortedcontainers/sorteddict.py \
+sortedcontainers/sortedlist.py \
+sortedcontainers/sortedlistwithkey.py \
+sortedcontainers/sortedset.py \
samtools-0.1.18/AUTHORS \
samtools-0.1.18/COPYING \
samtools-0.1.18/ChangeLog \
@@ -91,514 +100,588 @@ samtools-0.1.18/bcftools/prob1.c \
samtools-0.1.18/bcftools/prob1.h \
samtools-0.1.18/bcftools/vcf.c \
samtools-0.1.18/bcftools/vcfutils.pl \
-SeqAn-1.3/COPYING \
-SeqAn-1.3/README \
-SeqAn-1.3/seqan/chaining/chain_generic.h \
-SeqAn-1.3/seqan/chaining/rt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/score_zero.h \
-SeqAn-1.3/seqan/chaining/geom_distribution.h \
-SeqAn-1.3/seqan/chaining/chain_base.h \
-SeqAn-1.3/seqan/chaining/chaining_generated_forwards.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/skip_element.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_element.h \
-SeqAn-1.3/seqan/chaining/rt_sl_impl.h \
-SeqAn-1.3/seqan/chaining/chain_wrapper_point.h \
-SeqAn-1.3/seqan/chaining/rmt_compl_algos.h \
-SeqAn-1.3/seqan/chaining/rmt_base.h \
-SeqAn-1.3/seqan/chaining/skip_list.h \
-SeqAn-1.3/seqan/chaining/skip_list_iterator.h \
-SeqAn-1.3/seqan/chaining/skip_base_element.h \
-SeqAn-1.3/seqan/chaining/fragment.h \
-SeqAn-1.3/seqan/chaining/skip_pool_alloc.h \
-SeqAn-1.3/seqan/chaining/skip_list_impl.h \
-SeqAn-1.3/seqan/chaining/rt_skip_element.h \
-SeqAn-1.3/seqan/chaining/tree_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rmt_common_algos.h \
-SeqAn-1.3/seqan/chaining/score_manhattan.h \
-SeqAn-1.3/seqan/chaining/score_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rt_impl.h \
-SeqAn-1.3/seqan/chaining/tree_chain.h \
-SeqAn-1.3/seqan/chaining/tree_chain_utils.h \
-SeqAn-1.3/seqan/chaining/skip_list_base.h \
-SeqAn-1.3/seqan/chaining/rt_sl_def_algos.h \
-SeqAn-1.3/seqan/chaining/range_tree.h \
-SeqAn-1.3/seqan/chaining/rmt_def_algos.h \
-SeqAn-1.3/seqan/chaining/chain_point.h \
-SeqAn-1.3/seqan/chaining/rt_base.h \
-SeqAn-1.3/seqan/chaining/chain_meta_fragment.h \
-SeqAn-1.3/seqan/chaining/score_chain.h \
-SeqAn-1.3/seqan/chaining/rt_common_algos.h \
-SeqAn-1.3/seqan/chaining/skip_list_dynamic.h \
-SeqAn-1.3/seqan/chaining/rt_sl_base.h \
-SeqAn-1.3/seqan/chaining/skip_list_type.h \
-SeqAn-1.3/seqan/chaining/range_max_tree.h \
-SeqAn-1.3/seqan/chaining/rt_sl_compl_algos.h \
-SeqAn-1.3/seqan/file/file_format_cgviz.h \
-SeqAn-1.3/seqan/file/stream.h \
-SeqAn-1.3/seqan/file/file_format_embl.h \
-SeqAn-1.3/seqan/file/file_format_fasta.h \
-SeqAn-1.3/seqan/file/string_mmap.h \
-SeqAn-1.3/seqan/file/file_format_raw.h \
-SeqAn-1.3/seqan/file/string_external.h \
-SeqAn-1.3/seqan/file/file_filereader.h \
-SeqAn-1.3/seqan/file/file_cstyle.h \
-SeqAn-1.3/seqan/file/file_page_raid0.h \
-SeqAn-1.3/seqan/file/cstream.h \
-SeqAn-1.3/seqan/file/file_format_guess.h \
-SeqAn-1.3/seqan/file/file_base.h \
-SeqAn-1.3/seqan/file/file_format_mmap.h \
-SeqAn-1.3/seqan/file/file_forwards.h \
-SeqAn-1.3/seqan/file/file_array.h \
-SeqAn-1.3/seqan/file/meta.h \
-SeqAn-1.3/seqan/file/stream_algorithms.h \
-SeqAn-1.3/seqan/file/file_format.h \
-SeqAn-1.3/seqan/file/file_filereaderiterator.h \
-SeqAn-1.3/seqan/file/file_format_genbank.h \
-SeqAn-1.3/seqan/file/file_generated_forwards.h \
-SeqAn-1.3/seqan/file/file_format_fasta_align.h \
-SeqAn-1.3/seqan/file/chunk_collector.h \
-SeqAn-1.3/seqan/file/file_page.h \
-SeqAn-1.3/seqan/seeds.h \
-SeqAn-1.3/seqan/find_motif.h \
-SeqAn-1.3/seqan/LICENSE \
-SeqAn-1.3/seqan/find2/find_approx_find_begin.h \
-SeqAn-1.3/seqan/find2/find_finder_default.h \
-SeqAn-1.3/seqan/find2/find_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_multiple_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_hamming_simple.h \
-SeqAn-1.3/seqan/find2/find_pattern_wild_shiftand.h \
-SeqAn-1.3/seqan/find2/find_approx_dpsearch.h \
-SeqAn-1.3/seqan/find2/find_exact_shiftand.h \
-SeqAn-1.3/seqan/find2/find2_generated_forwards.h \
-SeqAn-1.3/seqan/find2/find_base.h \
-SeqAn-1.3/seqan/platform.h \
-SeqAn-1.3/seqan/sequence_journaled.h \
-SeqAn-1.3/seqan/chaining.h \
-SeqAn-1.3/seqan/score/score_generated_forwards.h \
-SeqAn-1.3/seqan/score/score_matrix_data.h \
-SeqAn-1.3/seqan/score/score_matrix.h \
-SeqAn-1.3/seqan/score/score_simple.h \
-SeqAn-1.3/seqan/score/score_base.h \
-SeqAn-1.3/seqan/score/score_edit.h \
-SeqAn-1.3/seqan/graph_algorithms.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entry.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_sorted_array.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_generated_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
-SeqAn-1.3/seqan/align/gaps_iterator_base.h \
-SeqAn-1.3/seqan/align/gaps_array.h \
-SeqAn-1.3/seqan/align/matrix_base.h \
-SeqAn-1.3/seqan/align/gaps_base.h \
-SeqAn-1.3/seqan/align/align_iterator_base.h \
-SeqAn-1.3/seqan/align/align_algorithms.h \
-SeqAn-1.3/seqan/align/align_hirschberg.h \
-SeqAn-1.3/seqan/align/align_local_dynprog.h \
-SeqAn-1.3/seqan/align/align_cols_base.h \
-SeqAn-1.3/seqan/align/align_generated_forwards.h \
-SeqAn-1.3/seqan/align/align_base.h \
-SeqAn-1.3/seqan/align/gaps_sumlist.h \
-SeqAn-1.3/seqan/align/align_local_dynprog_banded.h \
-SeqAn-1.3/seqan/align/align_dynprog.h \
-SeqAn-1.3/seqan/align/align_myers.h \
-SeqAn-1.3/seqan/align/hirschberg_set.h \
-SeqAn-1.3/seqan/align/align_trace.h \
-SeqAn-1.3/seqan/pipe/pipe_sampler.h \
-SeqAn-1.3/seqan/pipe/pipe_filter.h \
-SeqAn-1.3/seqan/pipe/pool_sorter.h \
-SeqAn-1.3/seqan/pipe/pipe_namer.h \
-SeqAn-1.3/seqan/pipe/pipe_joiner.h \
-SeqAn-1.3/seqan/pipe/pipe_base.h \
-SeqAn-1.3/seqan/pipe/pipe_echoer.h \
-SeqAn-1.3/seqan/pipe/pipe_caster.h \
-SeqAn-1.3/seqan/pipe/pipe_generated_forwards.h \
-SeqAn-1.3/seqan/pipe/pipe_counter.h \
-SeqAn-1.3/seqan/pipe/pool_mapper.h \
-SeqAn-1.3/seqan/pipe/pipe_edit_environment.h \
-SeqAn-1.3/seqan/pipe/pool_base.h \
-SeqAn-1.3/seqan/pipe/pipe_shifter.h \
-SeqAn-1.3/seqan/pipe/pipe_source.h \
-SeqAn-1.3/seqan/pipe/pipe_tupler.h \
-SeqAn-1.3/seqan/pipe/pipe_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_vertex.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_oracle.h \
-SeqAn-1.3/seqan/graph_types/graph_idmanager.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_adjacency.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_automaton.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_trie.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_bfs.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_dfs.h \
-SeqAn-1.3/seqan/graph_types/graph_property.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_fragment.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_outedge.h \
-SeqAn-1.3/seqan/graph_types/graph_utility_parsing.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_undirected.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_hmm.h \
-SeqAn-1.3/seqan/graph_types/graph_base.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_edge.h \
-SeqAn-1.3/seqan/graph_types/graph_edgestump.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_tree.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_wordgraph.h \
-SeqAn-1.3/seqan/graph_types/graph_types_generated_forwards.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_directed.h \
-SeqAn-1.3/seqan/graph_types/graph_drawing.h \
-SeqAn-1.3/seqan/graph_types/graph_interface.h \
-SeqAn-1.3/seqan/file.h \
-SeqAn-1.3/seqan/system.h \
-SeqAn-1.3/seqan/refinement.h \
-SeqAn-1.3/seqan/pipe.h \
-SeqAn-1.3/seqan/system/system_thread.h \
-SeqAn-1.3/seqan/system/system_base.h \
-SeqAn-1.3/seqan/system/system_event.h \
-SeqAn-1.3/seqan/system/file_directory.h \
-SeqAn-1.3/seqan/system/system_mutex.h \
-SeqAn-1.3/seqan/system/file_manual_forwards.h \
-SeqAn-1.3/seqan/system/system_generated_forwards.h \
-SeqAn-1.3/seqan/system/file_sync.h \
-SeqAn-1.3/seqan/system/file_async.h \
-SeqAn-1.3/seqan/system/system_sema.h \
-SeqAn-1.3/seqan/system/system_manual_forwards.h \
-SeqAn-1.3/seqan/misc/edit_environment.h \
-SeqAn-1.3/seqan/misc/misc_parsing.h \
-SeqAn-1.3/seqan/misc/misc_generated_forwards.h \
-SeqAn-1.3/seqan/misc/misc_base.h \
-SeqAn-1.3/seqan/misc/priority_type_heap.h \
-SeqAn-1.3/seqan/misc/priority_type_base.h \
-SeqAn-1.3/seqan/misc/misc_dequeue.h \
-SeqAn-1.3/seqan/misc/misc_set.h \
-SeqAn-1.3/seqan/misc/misc_map.h \
-SeqAn-1.3/seqan/misc/misc_svg.h \
-SeqAn-1.3/seqan/misc/misc_interval_tree.h \
-SeqAn-1.3/seqan/misc/misc_long_word.h \
-SeqAn-1.3/seqan/misc/misc_cmdparser.h \
-SeqAn-1.3/seqan/misc/misc_random.h \
-SeqAn-1.3/seqan/platform/platform_mingw.h \
-SeqAn-1.3/seqan/platform/platform_gcc.h \
-SeqAn-1.3/seqan/platform/platform_windows.h \
-SeqAn-1.3/seqan/platform/platform_solaris.h \
-SeqAn-1.3/seqan/platform/platform_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman.h \
-SeqAn-1.3/seqan/graph_align/graph_align_base.h \
-SeqAn-1.3/seqan/graph_align/graph_align_hirschberg.h \
-SeqAn-1.3/seqan/graph_align/graph_align_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_interface.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_config.h \
-SeqAn-1.3/seqan/parallel/parallel_generated_forwards.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_misc.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_primitives.h \
-SeqAn-1.3/seqan/parallel/parallel_macros.h \
-SeqAn-1.3/seqan/store/store_io_gff.h \
-SeqAn-1.3/seqan/store/store_library.h \
-SeqAn-1.3/seqan/store/store_read.h \
-SeqAn-1.3/seqan/store/store_annotation.h \
-SeqAn-1.3/seqan/store/store_intervaltree.h \
-SeqAn-1.3/seqan/store/store_io_ucsc.h \
-SeqAn-1.3/seqan/store/store_all.h \
-SeqAn-1.3/seqan/store/store_matepair.h \
-SeqAn-1.3/seqan/store/store_align_intervals.h \
-SeqAn-1.3/seqan/store/store_io.h \
-SeqAn-1.3/seqan/store/store_io_sam.h \
-SeqAn-1.3/seqan/store/store_align.h \
-SeqAn-1.3/seqan/store/store_io_bam.h \
-SeqAn-1.3/seqan/store/store_contig.h \
-SeqAn-1.3/seqan/store/store_generated_forwards.h \
-SeqAn-1.3/seqan/store/store_base.h \
-SeqAn-1.3/seqan/align.h \
-SeqAn-1.3/seqan/modifier/modifier_string.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet_expansion.h \
-SeqAn-1.3/seqan/modifier/modifier_shortcuts.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet.h \
-SeqAn-1.3/seqan/modifier/modifier_iterator.h \
-SeqAn-1.3/seqan/modifier/modifier_reverse.h \
-SeqAn-1.3/seqan/modifier/modifier_generated_forwards.h \
-SeqAn-1.3/seqan/modifier/modifier_view.h \
-SeqAn-1.3/seqan/modifier/modifier_functors.h \
-SeqAn-1.3/seqan/seeds2.h \
-SeqAn-1.3/seqan/index/index_sa_btree.h \
-SeqAn-1.3/seqan/index/find_quasar.h \
-SeqAn-1.3/seqan/index/index_esa_algs.h \
-SeqAn-1.3/seqan/index/index_skew7.h \
-SeqAn-1.3/seqan/index/index_pizzachili.h \
-SeqAn-1.3/seqan/index/index_sa_lss.h \
-SeqAn-1.3/seqan/index/pump_extender7.h \
-SeqAn-1.3/seqan/index/index_shawarma.h \
-SeqAn-1.3/seqan/index/find_index_approx.h \
-SeqAn-1.3/seqan/index/index_lcp.h \
-SeqAn-1.3/seqan/index/find_swift.h \
-SeqAn-1.3/seqan/index/shape_threshold.h \
-SeqAn-1.3/seqan/index/pizzachili_api.h \
-SeqAn-1.3/seqan/index/index_sa_mm.h \
-SeqAn-1.3/seqan/index/index_esa_stree.h \
-SeqAn-1.3/seqan/index/index_qgram.h \
-SeqAn-1.3/seqan/index/pump_extender3.h \
-SeqAn-1.3/seqan/index/shape_onegapped.h \
-SeqAn-1.3/seqan/index/find_index_qgram.h \
-SeqAn-1.3/seqan/index/index_skew3.h \
-SeqAn-1.3/seqan/index/index_childtab.h \
-SeqAn-1.3/seqan/index/pipe_merger7.h \
-SeqAn-1.3/seqan/index/pipe_merger3.h \
-SeqAn-1.3/seqan/index/repeat_base.h \
-SeqAn-1.3/seqan/index/index_pizzachili_find.h \
-SeqAn-1.3/seqan/index/index_sa_qsort.h \
-SeqAn-1.3/seqan/index/index_shims.h \
-SeqAn-1.3/seqan/index/index_manual_forwards.h \
-SeqAn-1.3/seqan/index/shape_base.h \
-SeqAn-1.3/seqan/index/shape_predefined.h \
-SeqAn-1.3/seqan/index/index_pizzachili_string.h \
-SeqAn-1.3/seqan/index/index_generated_forwards.h \
-SeqAn-1.3/seqan/index/find_index_esa.h \
-SeqAn-1.3/seqan/index/pump_separator7.h \
-SeqAn-1.3/seqan/index/index_esa_base.h \
-SeqAn-1.3/seqan/index/radix.h \
-SeqAn-1.3/seqan/index/index_skew7_multi.h \
-SeqAn-1.3/seqan/index/index_esa_algs_multi.h \
-SeqAn-1.3/seqan/index/index_base.h \
-SeqAn-1.3/seqan/index/shape_gapped.h \
-SeqAn-1.3/seqan/index/index_lcp_tree.h \
-SeqAn-1.3/seqan/index/index_esa_drawing.h \
-SeqAn-1.3/seqan/index/find_index.h \
-SeqAn-1.3/seqan/index/pump_lcp_core.h \
-SeqAn-1.3/seqan/index/index_dfi.h \
-SeqAn-1.3/seqan/index/index_sa_bwtwalk.h \
-SeqAn-1.3/seqan/index/index_qgram_openaddressing.h \
-SeqAn-1.3/seqan/index/index_bwt.h \
-SeqAn-1.3/seqan/index/index_wotd.h \
-SeqAn-1.3/seqan/statistics/statistics_base.h \
-SeqAn-1.3/seqan/statistics/statistics_markov_model.h \
-SeqAn-1.3/seqan/statistics/statistics_generated_forwards.h \
-SeqAn-1.3/seqan/score.h \
-SeqAn-1.3/seqan/sequence.h \
-SeqAn-1.3/seqan/parallel.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithms_generated_forwards.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_hmm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_lis_his.h \
-SeqAn-1.3/seqan/blast.h \
-SeqAn-1.3/seqan/store.h \
-SeqAn-1.3/seqan/graph_align.h \
-SeqAn-1.3/seqan/random/random_lognormal.h \
-SeqAn-1.3/seqan/random/ext_MersenneTwister.h \
-SeqAn-1.3/seqan/random/random_generated_forwards.h \
-SeqAn-1.3/seqan/random/random_rng_functor.h \
-SeqAn-1.3/seqan/random/random_base.h \
-SeqAn-1.3/seqan/random/random_uniform.h \
-SeqAn-1.3/seqan/random/random_shuffle.h \
-SeqAn-1.3/seqan/random/random_normal.h \
-SeqAn-1.3/seqan/random/random_geometric.h \
-SeqAn-1.3/seqan/random/random_mt19937.h \
-SeqAn-1.3/seqan/basic.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_progressive.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_distance.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_io.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_kmer.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_refinement.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_msa.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
-SeqAn-1.3/seqan/graph_msa/graph_msa_generated_forwards.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_library.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_base.h \
-SeqAn-1.3/seqan/basic/basic_sse2.h \
-SeqAn-1.3/seqan/basic/basic_forwards.h \
-SeqAn-1.3/seqan/basic/basic_testing.h \
-SeqAn-1.3/seqan/basic/basic_counted_ptr.h \
-SeqAn-1.3/seqan/basic/basic_iterator_base.h \
-SeqAn-1.3/seqan/basic/basic_pointer.h \
-SeqAn-1.3/seqan/basic/basic_allocator_chunkpool.h \
-SeqAn-1.3/seqan/basic/basic_parallelism.h \
-SeqAn-1.3/seqan/basic/basic_allocator_singlepool.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adaptor.h \
-SeqAn-1.3/seqan/basic/basic_profile.h \
-SeqAn-1.3/seqan/basic/basic_tag.h \
-SeqAn-1.3/seqan/basic/basic_compare.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface.h \
-SeqAn-1.3/seqan/basic/basic_iterator_simple.h \
-SeqAn-1.3/seqan/basic/basic_definition.h \
-SeqAn-1.3/seqan/basic/basic_operator.h \
-SeqAn-1.3/seqan/basic/basic_holder_dynamic.h \
-SeqAn-1.3/seqan/basic/basic_allocator_multipool.h \
-SeqAn-1.3/seqan/basic/basic_proxy.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple_tabs.h \
-SeqAn-1.3/seqan/basic/basic_metaprogramming.h \
-SeqAn-1.3/seqan/basic/basic_host.h \
-SeqAn-1.3/seqan/basic/basic_allocator_to_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_interface.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface2.h \
-SeqAn-1.3/seqan/basic/basic_logvalue.h \
-SeqAn-1.3/seqan/basic/basic_volatile_ptr.h \
-SeqAn-1.3/seqan/basic/basic_debug.h \
-SeqAn-1.3/seqan/basic/basic_profchar.h \
-SeqAn-1.3/seqan/basic/basic_aggregates.h \
-SeqAn-1.3/seqan/basic/basic_transport.h \
-SeqAn-1.3/seqan/basic/basic_holder.h \
-SeqAn-1.3/seqan/basic/basic_converter.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple.h \
-SeqAn-1.3/seqan/basic/basic_type.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adapt_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_simple.h \
-SeqAn-1.3/seqan/basic/basic_iterator.h \
-SeqAn-1.3/seqan/basic/basic_generated_forwards.h \
-SeqAn-1.3/seqan/basic/basic_iterator_position.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_trait_basic.h \
-SeqAn-1.3/seqan/sequence/sequence_forwards.h \
-SeqAn-1.3/seqan/sequence/segment_infix.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_tight.h \
-SeqAn-1.3/seqan/sequence/segment_base.h \
-SeqAn-1.3/seqan/sequence/sequence_lexical.h \
-SeqAn-1.3/seqan/sequence/string_cstyle.h \
-SeqAn-1.3/seqan/sequence/sequence_concatenator.h \
-SeqAn-1.3/seqan/sequence/string_packed.h \
-SeqAn-1.3/seqan/sequence/sequence_stream.h \
-SeqAn-1.3/seqan/sequence/sequence_shortcuts.h \
-SeqAn-1.3/seqan/sequence/adapt_std_list.h \
-SeqAn-1.3/seqan/sequence/string_base.h \
-SeqAn-1.3/seqan/sequence/string_set_owner.h \
-SeqAn-1.3/seqan/sequence/adapt_std_string.h \
-SeqAn-1.3/seqan/sequence/sequence_generated_forwards.h \
-SeqAn-1.3/seqan/sequence/string_set_concat_direct.h \
-SeqAn-1.3/seqan/sequence/sequence_interface.h \
-SeqAn-1.3/seqan/sequence/adapt_array_pointer.h \
-SeqAn-1.3/seqan/sequence/segment_suffix.h \
-SeqAn-1.3/seqan/sequence/string_array.h \
-SeqAn-1.3/seqan/sequence/iter_concat_virtual.h \
-SeqAn-1.3/seqan/sequence/segment_prefix.h \
-SeqAn-1.3/seqan/sequence/string_block.h \
-SeqAn-1.3/seqan/sequence/string_set_base.h \
-SeqAn-1.3/seqan/sequence/adapt_std_vector.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_generous.h \
-SeqAn-1.3/seqan/sequence/string_alloc.h \
-SeqAn-1.3/seqan/modifier.h \
-SeqAn-1.3/seqan/random.h \
-SeqAn-1.3/seqan/statistics.h \
-SeqAn-1.3/seqan/consensus.h \
-SeqAn-1.3/seqan/find.h \
-SeqAn-1.3/seqan/find2.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_inexact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_fragment.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_annotation.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_align.h \
-SeqAn-1.3/seqan/refinement/refinement_generated_forwards.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_scoring.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact_iterative.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align_adapt.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_aligngraph.h \
-SeqAn-1.3/seqan/seeds/global_seed_chain.h \
-SeqAn-1.3/seqan/seeds/seedSet_score.h \
-SeqAn-1.3/seqan/seeds/seeds_generated_forwards.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align_affine.h \
-SeqAn-1.3/seqan/seeds/banded_align.h \
-SeqAn-1.3/seqan/seeds/memoryManager_int.h \
-SeqAn-1.3/seqan/seeds/seedHandlingTags.h \
-SeqAn-1.3/seqan/seeds/seedSet_iterator.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align.h \
-SeqAn-1.3/seqan/seeds/seed_multi.h \
-SeqAn-1.3/seqan/seeds/seedSet_base.h \
-SeqAn-1.3/seqan/seeds/propertyMap.h \
-SeqAn-1.3/seqan/seeds/memoryManager_base.h \
-SeqAn-1.3/seqan/seeds/seed_base.h \
-SeqAn-1.3/seqan/graph_msa.h \
-SeqAn-1.3/seqan/consensus/consensus_score.h \
-SeqAn-1.3/seqan/consensus/consensus_base.h \
-SeqAn-1.3/seqan/consensus/consensus_generated_forwards.h \
-SeqAn-1.3/seqan/consensus/consensus_realign.h \
-SeqAn-1.3/seqan/consensus/consensus_library.h \
-SeqAn-1.3/seqan/map/map_generated_forwards.h \
-SeqAn-1.3/seqan/map/map_base.h \
-SeqAn-1.3/seqan/map/map_chooser.h \
-SeqAn-1.3/seqan/map/map_vector.h \
-SeqAn-1.3/seqan/map/sumlist_mini.h \
-SeqAn-1.3/seqan/map/map_adapter_stl.h \
-SeqAn-1.3/seqan/map/sumlist.h \
-SeqAn-1.3/seqan/map/map_skiplist.h \
-SeqAn-1.3/seqan/map/sumlist_skip.h \
-SeqAn-1.3/seqan/blast/blast_stream_report.h \
-SeqAn-1.3/seqan/blast/blast_run.h \
-SeqAn-1.3/seqan/blast/blast_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hsp.h \
-SeqAn-1.3/seqan/blast/blast_base.h \
-SeqAn-1.3/seqan/blast/blast_hit.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit.h \
-SeqAn-1.3/seqan/blast/blast_iterator.h \
-SeqAn-1.3/seqan/blast/blast_parsing.h \
-SeqAn-1.3/seqan/blast/blast_report.h \
-SeqAn-1.3/seqan/blast/blast_generated_forwards.h \
-SeqAn-1.3/seqan/blast/blast_stream_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hit_iterator.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_base.h \
-SeqAn-1.3/seqan/seeds2/seeds_extension.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_unordered.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_base.h \
-SeqAn-1.3/seqan/seeds2/seeds2_generated_forwards.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_diagonal.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_simple.h \
-SeqAn-1.3/seqan/seeds2/seeds_base.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_combination.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_non_scored.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_linear.h \
-SeqAn-1.3/seqan/seeds2/align_chain_banded.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_linear.h \
-SeqAn-1.3/seqan/seeds2/basic_iter_indirect.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_gusfield.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_chained.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_scored.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_base.h \
-SeqAn-1.3/seqan/map.h \
-SeqAn-1.3/seqan/find/find_pattern_base.h \
-SeqAn-1.3/seqan/find/find_multiple_shiftand.h \
-SeqAn-1.3/seqan/find/find_generated_forwards.h \
-SeqAn-1.3/seqan/find/find_horspool.h \
-SeqAn-1.3/seqan/find/find_abndm.h \
-SeqAn-1.3/seqan/find/find_score.h \
-SeqAn-1.3/seqan/find/find_set_horspool.h \
-SeqAn-1.3/seqan/find/find_wild_shiftand.h \
-SeqAn-1.3/seqan/find/find_hamming_simple.h \
-SeqAn-1.3/seqan/find/find_shiftand.h \
-SeqAn-1.3/seqan/find/find_begin.h \
-SeqAn-1.3/seqan/find/find_shiftor.h \
-SeqAn-1.3/seqan/find/find_wumanber.h \
-SeqAn-1.3/seqan/find/find_multi.h \
-SeqAn-1.3/seqan/find/find_simple.h \
-SeqAn-1.3/seqan/find/find_bndm.h \
-SeqAn-1.3/seqan/find/find_pex.h \
-SeqAn-1.3/seqan/find/find_bom.h \
-SeqAn-1.3/seqan/find/find_ahocorasick.h \
-SeqAn-1.3/seqan/find/find_multiple_bfam.h \
-SeqAn-1.3/seqan/find/find_myers_ukkonen.h \
-SeqAn-1.3/seqan/find/find_base.h \
-SeqAn-1.3/seqan/index.h \
-SeqAn-1.3/seqan/graph_types.h \
-SeqAn-1.3/seqan/find_motif/profile.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pmsp.h \
-SeqAn-1.3/seqan/find_motif/sequence_model_types.h \
-SeqAn-1.3/seqan/find_motif/find_motif_base.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_p.h \
-SeqAn-1.3/seqan/find_motif/find_motif_epatternbranching.h \
-SeqAn-1.3/seqan/find_motif/find_motif_projection.h \
-SeqAn-1.3/seqan/find_motif/find_motif_generated_forwards.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_c.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_base.h \
-SeqAn-1.3/seqan/find_motif/em_algorithm.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pms1.h \
-SeqAn-1.3/seqan/find_motif/frequency_distribution.h \
-SeqAn-1.3/seqan.h
+SeqAn-1.4.2/LICENSE \
+SeqAn-1.4.2/README.rst \
+SeqAn-1.4.2/seqan/align/align_base.h \
+SeqAn-1.4.2/seqan/align/align_cols.h \
+SeqAn-1.4.2/seqan/align/align_config.h \
+SeqAn-1.4.2/seqan/align/align_iterator_base.h \
+SeqAn-1.4.2/seqan/align/alignment_algorithm_tags.h \
+SeqAn-1.4.2/seqan/align/alignment_operations.h \
+SeqAn-1.4.2/seqan/align/align_metafunctions.h \
+SeqAn-1.4.2/seqan/align/align_traceback.h \
+SeqAn-1.4.2/seqan/align/dp_algorithm_impl.h \
+SeqAn-1.4.2/seqan/align/dp_band.h \
+SeqAn-1.4.2/seqan/align/dp_cell_affine.h \
+SeqAn-1.4.2/seqan/align/dp_cell.h \
+SeqAn-1.4.2/seqan/align/dp_cell_linear.h \
+SeqAn-1.4.2/seqan/align/dp_formula_affine.h \
+SeqAn-1.4.2/seqan/align/dp_formula.h \
+SeqAn-1.4.2/seqan/align/dp_formula_linear.h \
+SeqAn-1.4.2/seqan/align/dp_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_trace_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_meta_info.h \
+SeqAn-1.4.2/seqan/align/dp_profile.h \
+SeqAn-1.4.2/seqan/align/dp_scout.h \
+SeqAn-1.4.2/seqan/align/dp_setup.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_adaptor.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_impl.h \
+SeqAn-1.4.2/seqan/align/dp_trace_segment.h \
+SeqAn-1.4.2/seqan/align/evaluate_alignment.h \
+SeqAn-1.4.2/seqan/align/gap_anchor.h \
+SeqAn-1.4.2/seqan/align/gapped_value_type.h \
+SeqAn-1.4.2/seqan/align/gaps_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_array.h \
+SeqAn-1.4.2/seqan/align/gaps_base.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_array.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_base.h \
+SeqAn-1.4.2/seqan/align/global_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/global_alignment_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_specialized.h \
+SeqAn-1.4.2/seqan/align/global_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align.h \
+SeqAn-1.4.2/seqan/align/INFO \
+SeqAn-1.4.2/seqan/align/local_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_banded_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/matrix_base.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_argument.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_ctd_support.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_exceptions.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_option.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_type_support.h \
+SeqAn-1.4.2/seqan/arg_parse/argument_parser.h \
+SeqAn-1.4.2/seqan/arg_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/INFO \
+SeqAn-1.4.2/seqan/arg_parse/tool_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/xml_support.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record_util.h \
+SeqAn-1.4.2/seqan/bam_io/bam_header_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_bai.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_base.h \
+SeqAn-1.4.2/seqan/bam_io/bam_io_context.h \
+SeqAn-1.4.2/seqan/bam_io/bam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/bam_sam_conversion.h \
+SeqAn-1.4.2/seqan/bam_io/bam_stream.h \
+SeqAn-1.4.2/seqan/bam_io/bam_tags_dict.h \
+SeqAn-1.4.2/seqan/bam_io/bam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/cigar.h \
+SeqAn-1.4.2/seqan/bam_io.h \
+SeqAn-1.4.2/seqan/bam_io/INFO \
+SeqAn-1.4.2/seqan/bam_io/read_bam.h \
+SeqAn-1.4.2/seqan/bam_io/read_sam.h \
+SeqAn-1.4.2/seqan/bam_io/sam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/sam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/write_bam.h \
+SeqAn-1.4.2/seqan/bam_io/write_sam.h \
+SeqAn-1.4.2/seqan/bam_io/xam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/xam_writer.h \
+SeqAn-1.4.2/seqan/basic/aggregate_concept.h \
+SeqAn-1.4.2/seqan/basic/allocator_chunkpool.h \
+SeqAn-1.4.2/seqan/basic/allocator_interface.h \
+SeqAn-1.4.2/seqan/basic/allocator_multipool.h \
+SeqAn-1.4.2/seqan/basic/allocator_simple.h \
+SeqAn-1.4.2/seqan/basic/allocator_singlepool.h \
+SeqAn-1.4.2/seqan/basic/allocator_to_std.h \
+SeqAn-1.4.2/seqan/basic/alphabet_adapt_builtins.h \
+SeqAn-1.4.2/seqan/basic/alphabet_bio.h \
+SeqAn-1.4.2/seqan/basic/alphabet_concept.h \
+SeqAn-1.4.2/seqan/basic/alphabet_math.h \
+SeqAn-1.4.2/seqan/basic/alphabet_profile.h \
+SeqAn-1.4.2/seqan/basic/alphabet_qualities.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_funcs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_tabs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_simple_type.h \
+SeqAn-1.4.2/seqan/basic/alphabet_storage.h \
+SeqAn-1.4.2/seqan/basic/array_construct_destruct.h \
+SeqAn-1.4.2/seqan/basic/basic_aggregate.h \
+SeqAn-1.4.2/seqan/basic/basic_allocator.h \
+SeqAn-1.4.2/seqan/basic/basic_alphabet.h \
+SeqAn-1.4.2/seqan/basic/basic_concept.h \
+SeqAn-1.4.2/seqan/basic/basic_container.h \
+SeqAn-1.4.2/seqan/basic/basic_debug.h \
+SeqAn-1.4.2/seqan/basic/basic_exception.h \
+SeqAn-1.4.2/seqan/basic/basic_fundamental.h \
+SeqAn-1.4.2/seqan/basic/basic_iterator.h \
+SeqAn-1.4.2/seqan/basic/basic_math.h \
+SeqAn-1.4.2/seqan/basic/basic_metaprogramming.h \
+SeqAn-1.4.2/seqan/basic/basic_parallelism.h \
+SeqAn-1.4.2/seqan/basic/basic_proxy.h \
+SeqAn-1.4.2/seqan/basic/basic_smart_pointer.h \
+SeqAn-1.4.2/seqan/basic/basic_tangle.h \
+SeqAn-1.4.2/seqan/basic/basic_type.h \
+SeqAn-1.4.2/seqan/basic/boost_preprocessor_subset.h \
+SeqAn-1.4.2/seqan/basic/builtin_functions.h \
+SeqAn-1.4.2/seqan/basic/concept_checking.h \
+SeqAn-1.4.2/seqan/basic/container_concept.h \
+SeqAn-1.4.2/seqan/basic/debug_helper.h \
+SeqAn-1.4.2/seqan/basic/debug_test_system.h \
+SeqAn-1.4.2/seqan/basic/fundamental_comparison.h \
+SeqAn-1.4.2/seqan/basic/fundamental_concepts.h \
+SeqAn-1.4.2/seqan/basic/fundamental_conversion.h \
+SeqAn-1.4.2/seqan/basic/fundamental_metafunctions.h \
+SeqAn-1.4.2/seqan/basic/fundamental_tags.h \
+SeqAn-1.4.2/seqan/basic/fundamental_transport.h \
+SeqAn-1.4.2/seqan/basic.h \
+SeqAn-1.4.2/seqan/basic/holder_base.h \
+SeqAn-1.4.2/seqan/basic/holder_simple.h \
+SeqAn-1.4.2/seqan/basic/holder_tristate.h \
+SeqAn-1.4.2/seqan/basic/hosted_type_interface.h \
+SeqAn-1.4.2/seqan/basic/INFO \
+SeqAn-1.4.2/seqan/basic/iterator_adaptor.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_pointer.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_std.h \
+SeqAn-1.4.2/seqan/basic/iterator_base.h \
+SeqAn-1.4.2/seqan/basic/iterator_concept.h \
+SeqAn-1.4.2/seqan/basic/iterator_interface.h \
+SeqAn-1.4.2/seqan/basic/iterator_position.h \
+SeqAn-1.4.2/seqan/basic/macro_deprecated.h \
+SeqAn-1.4.2/seqan/basic/math_functions.h \
+SeqAn-1.4.2/seqan/basic/math_log_space_value.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_control.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_enable_if.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_logic.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_math.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_type.h \
+SeqAn-1.4.2/seqan/basic/pair_base.h \
+SeqAn-1.4.2/seqan/basic/pair_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/pair_packed.h \
+SeqAn-1.4.2/seqan/basic/profiling.h \
+SeqAn-1.4.2/seqan/basic/proxy_base.h \
+SeqAn-1.4.2/seqan/basic/proxy_iterator.h \
+SeqAn-1.4.2/seqan/basic/test_system.h \
+SeqAn-1.4.2/seqan/basic/triple_base.h \
+SeqAn-1.4.2/seqan/basic/triple_packed.h \
+SeqAn-1.4.2/seqan/basic/tuple_base.h \
+SeqAn-1.4.2/seqan/basic/tuple_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/volatile_ptr.h \
+SeqAn-1.4.2/seqan/consensus/consensus_base.h \
+SeqAn-1.4.2/seqan/consensus/consensus_library.h \
+SeqAn-1.4.2/seqan/consensus/consensus_realign.h \
+SeqAn-1.4.2/seqan/consensus/consensus_score.h \
+SeqAn-1.4.2/seqan/consensus.h \
+SeqAn-1.4.2/seqan/consensus/INFO \
+SeqAn-1.4.2/seqan/file/chunk_collector.h \
+SeqAn-1.4.2/seqan/file/cstream.h \
+SeqAn-1.4.2/seqan/file/file_base.h \
+SeqAn-1.4.2/seqan/file/file_cstyle.h \
+SeqAn-1.4.2/seqan/file/file_filereader.h \
+SeqAn-1.4.2/seqan/file/file_filereaderiterator.h \
+SeqAn-1.4.2/seqan/file/file_format_cgviz.h \
+SeqAn-1.4.2/seqan/file/file_format_embl.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta_align.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta.h \
+SeqAn-1.4.2/seqan/file/file_format_genbank.h \
+SeqAn-1.4.2/seqan/file/file_format_guess.h \
+SeqAn-1.4.2/seqan/file/file_format.h \
+SeqAn-1.4.2/seqan/file/file_format_mmap.h \
+SeqAn-1.4.2/seqan/file/file_format_raw.h \
+SeqAn-1.4.2/seqan/file/file_forwards.h \
+SeqAn-1.4.2/seqan/file/file_interface.h \
+SeqAn-1.4.2/seqan/file/file_mapping.h \
+SeqAn-1.4.2/seqan/file/file_page.h \
+SeqAn-1.4.2/seqan/file.h \
+SeqAn-1.4.2/seqan/file/INFO \
+SeqAn-1.4.2/seqan/file/meta.h \
+SeqAn-1.4.2/seqan/file/stream_algorithms.h \
+SeqAn-1.4.2/seqan/file/stream.h \
+SeqAn-1.4.2/seqan/file/string_external.h \
+SeqAn-1.4.2/seqan/file/string_mmap.h \
+SeqAn-1.4.2/seqan/find/find_abndm.h \
+SeqAn-1.4.2/seqan/find/find_ahocorasick.h \
+SeqAn-1.4.2/seqan/find/find_base.h \
+SeqAn-1.4.2/seqan/find/find_begin.h \
+SeqAn-1.4.2/seqan/find/find_bndm.h \
+SeqAn-1.4.2/seqan/find/find_bom.h \
+SeqAn-1.4.2/seqan/find/find_hamming_simple.h \
+SeqAn-1.4.2/seqan/find/find_horspool.h \
+SeqAn-1.4.2/seqan/find/find_multi.h \
+SeqAn-1.4.2/seqan/find/find_multiple_bfam.h \
+SeqAn-1.4.2/seqan/find/find_multiple_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_myers_ukkonen.h \
+SeqAn-1.4.2/seqan/find/find_pattern_base.h \
+SeqAn-1.4.2/seqan/find/find_pex.h \
+SeqAn-1.4.2/seqan/find/find_score.h \
+SeqAn-1.4.2/seqan/find/find_set_horspool.h \
+SeqAn-1.4.2/seqan/find/find_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_shiftor.h \
+SeqAn-1.4.2/seqan/find/find_simple.h \
+SeqAn-1.4.2/seqan/find/find_wild_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_wumanber.h \
+SeqAn-1.4.2/seqan/find.h \
+SeqAn-1.4.2/seqan/find/INFO \
+SeqAn-1.4.2/seqan/gff_io/gff_io_base.h \
+SeqAn-1.4.2/seqan/gff_io/gff_io_context.h \
+SeqAn-1.4.2/seqan/gff_io/gff_stream.h \
+SeqAn-1.4.2/seqan/gff_io.h \
+SeqAn-1.4.2/seqan/gff_io/INFO \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_hmm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_lis_his.h \
+SeqAn-1.4.2/seqan/graph_algorithms.h \
+SeqAn-1.4.2/seqan/graph_algorithms/INFO \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_aligngraph.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_align.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_annotation.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact_iterative.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_fragment.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_inexact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_scoring.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align_adapt.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align.h \
+SeqAn-1.4.2/seqan/graph_align.h \
+SeqAn-1.4.2/seqan/graph_align/INFO \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_base.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_distance.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_io.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_kmer.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_library.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_progressive.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_refinement.h \
+SeqAn-1.4.2/seqan/graph_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/INFO \
+SeqAn-1.4.2/seqan/graph_types/graph_base.h \
+SeqAn-1.4.2/seqan/graph_types/graph_drawing.h \
+SeqAn-1.4.2/seqan/graph_types/graph_edgestump.h \
+SeqAn-1.4.2/seqan/graph_types/graph_idmanager.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_automaton.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_directed.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_fragment.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_hmm.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_oracle.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_tree.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_trie.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_undirected.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_wordgraph.h \
+SeqAn-1.4.2/seqan/graph_types/graph_interface.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_adjacency.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_bfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_dfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_edge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_outedge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_vertex.h \
+SeqAn-1.4.2/seqan/graph_types/graph_property.h \
+SeqAn-1.4.2/seqan/graph_types/graph_utility_parsing.h \
+SeqAn-1.4.2/seqan/graph_types.h \
+SeqAn-1.4.2/seqan/graph_types/INFO \
+SeqAn-1.4.2/seqan/index/find_index_approx.h \
+SeqAn-1.4.2/seqan/index/find_index_esa.h \
+SeqAn-1.4.2/seqan/index/find_index.h \
+SeqAn-1.4.2/seqan/index/find_index_qgram.h \
+SeqAn-1.4.2/seqan/index/find_pigeonhole.h \
+SeqAn-1.4.2/seqan/index/find_quasar.h \
+SeqAn-1.4.2/seqan/index/find_swift.h \
+SeqAn-1.4.2/seqan/index.h \
+SeqAn-1.4.2/seqan/index/index_base.h \
+SeqAn-1.4.2/seqan/index/index_bwt.h \
+SeqAn-1.4.2/seqan/index/index_childtab.h \
+SeqAn-1.4.2/seqan/index/index_dfi.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs_multi.h \
+SeqAn-1.4.2/seqan/index/index_esa_base.h \
+SeqAn-1.4.2/seqan/index/index_esa_drawing.h \
+SeqAn-1.4.2/seqan/index/index_esa_stree.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_doc.h \
+SeqAn-1.4.2/seqan/index/index_fm_dox.h \
+SeqAn-1.4.2/seqan/index/index_fm.h \
+SeqAn-1.4.2/seqan/index/index_fm_lf_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_prefix_sum_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_bms.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_wt.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_sentinel_rank_dictionary.h \
+SeqAn-1.4.2/seqan/index/index_fm_sparse_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_stree.h \
+SeqAn-1.4.2/seqan/index/index_forwards.h \
+SeqAn-1.4.2/seqan/index/index_lcp.h \
+SeqAn-1.4.2/seqan/index/index_lcp_tree.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_find.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_string.h \
+SeqAn-1.4.2/seqan/index/index_qgram.h \
+SeqAn-1.4.2/seqan/index/index_qgram_openaddressing.h \
+SeqAn-1.4.2/seqan/index/index_sa_btree.h \
+SeqAn-1.4.2/seqan/index/index_sa_bwtwalk.h \
+SeqAn-1.4.2/seqan/index/index_sa_lss.h \
+SeqAn-1.4.2/seqan/index/index_sa_mm.h \
+SeqAn-1.4.2/seqan/index/index_sa_qsort.h \
+SeqAn-1.4.2/seqan/index/index_shawarma.h \
+SeqAn-1.4.2/seqan/index/index_shims.h \
+SeqAn-1.4.2/seqan/index/index_skew3.h \
+SeqAn-1.4.2/seqan/index/index_skew7.h \
+SeqAn-1.4.2/seqan/index/index_skew7_multi.h \
+SeqAn-1.4.2/seqan/index/index_wotd.h \
+SeqAn-1.4.2/seqan/index/INFO \
+SeqAn-1.4.2/seqan/index/pipe_merger3.h \
+SeqAn-1.4.2/seqan/index/pipe_merger7.h \
+SeqAn-1.4.2/seqan/index/pizzachili_api.h \
+SeqAn-1.4.2/seqan/index/pump_extender3.h \
+SeqAn-1.4.2/seqan/index/pump_extender7.h \
+SeqAn-1.4.2/seqan/index/pump_lcp_core.h \
+SeqAn-1.4.2/seqan/index/pump_separator7.h \
+SeqAn-1.4.2/seqan/index/radix.h \
+SeqAn-1.4.2/seqan/index/repeat_base.h \
+SeqAn-1.4.2/seqan/index/shape_base.h \
+SeqAn-1.4.2/seqan/index/shape_gapped.h \
+SeqAn-1.4.2/seqan/index/shape_onegapped.h \
+SeqAn-1.4.2/seqan/index/shape_predefined.h \
+SeqAn-1.4.2/seqan/index/shape_threshold.h \
+SeqAn-1.4.2/seqan/LICENSE \
+SeqAn-1.4.2/seqan/map.h \
+SeqAn-1.4.2/seqan/map/INFO \
+SeqAn-1.4.2/seqan/map/map_adapter_stl.h \
+SeqAn-1.4.2/seqan/map/map_base.h \
+SeqAn-1.4.2/seqan/map/map_chooser.h \
+SeqAn-1.4.2/seqan/map/map_skiplist.h \
+SeqAn-1.4.2/seqan/map/map_vector.h \
+SeqAn-1.4.2/seqan/map/sumlist.h \
+SeqAn-1.4.2/seqan/map/sumlist_mini.h \
+SeqAn-1.4.2/seqan/map/sumlist_skip.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdoption.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_ctd_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_parse.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_type_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/INFO \
+SeqAn-1.4.2/seqan/misc/edit_environment.h \
+SeqAn-1.4.2/seqan/misc/INFO \
+SeqAn-1.4.2/seqan/misc/misc_accumulators.h \
+SeqAn-1.4.2/seqan/misc/misc_base.h \
+SeqAn-1.4.2/seqan/misc/misc_bit_twiddling.h \
+SeqAn-1.4.2/seqan/misc/misc_cmdparser.h \
+SeqAn-1.4.2/seqan/misc/misc_dequeue.h \
+SeqAn-1.4.2/seqan/misc/misc_interval_tree.h \
+SeqAn-1.4.2/seqan/misc/misc_map.h \
+SeqAn-1.4.2/seqan/misc/misc_memset.h \
+SeqAn-1.4.2/seqan/misc/misc_name_store_cache.h \
+SeqAn-1.4.2/seqan/misc/misc_parsing.h \
+SeqAn-1.4.2/seqan/misc/misc_set.h \
+SeqAn-1.4.2/seqan/misc/misc_sse2.h \
+SeqAn-1.4.2/seqan/misc/misc_svg.h \
+SeqAn-1.4.2/seqan/misc/misc_terminal.h \
+SeqAn-1.4.2/seqan/misc/misc_union_find.h \
+SeqAn-1.4.2/seqan/misc/priority_type_base.h \
+SeqAn-1.4.2/seqan/misc/priority_type_heap.h \
+SeqAn-1.4.2/seqan/modifier.h \
+SeqAn-1.4.2/seqan/modifier/INFO \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet_expansion.h \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet.h \
+SeqAn-1.4.2/seqan/modifier/modifier_functors.h \
+SeqAn-1.4.2/seqan/modifier/modifier_iterator.h \
+SeqAn-1.4.2/seqan/modifier/modifier_reverse.h \
+SeqAn-1.4.2/seqan/modifier/modifier_shortcuts.h \
+SeqAn-1.4.2/seqan/modifier/modifier_string.h \
+SeqAn-1.4.2/seqan/modifier/modifier_view.h \
+SeqAn-1.4.2/seqan/parallel.h \
+SeqAn-1.4.2/seqan/parallel/INFO \
+SeqAn-1.4.2/seqan/parallel/parallel_algorithms.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_misc.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_primitives.h \
+SeqAn-1.4.2/seqan/parallel/parallel_macros.h \
+SeqAn-1.4.2/seqan/parallel/parallel_splitting.h \
+SeqAn-1.4.2/seqan/parallel/parallel_tags.h \
+SeqAn-1.4.2/seqan/pipe.h \
+SeqAn-1.4.2/seqan/pipe/INFO \
+SeqAn-1.4.2/seqan/pipe/pipe_base.h \
+SeqAn-1.4.2/seqan/pipe/pipe_caster.h \
+SeqAn-1.4.2/seqan/pipe/pipe_counter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_echoer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_edit_environment.h \
+SeqAn-1.4.2/seqan/pipe/pipe_filter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_iterator.h \
+SeqAn-1.4.2/seqan/pipe/pipe_joiner.h \
+SeqAn-1.4.2/seqan/pipe/pipe_namer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_sampler.h \
+SeqAn-1.4.2/seqan/pipe/pipe_shifter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_source.h \
+SeqAn-1.4.2/seqan/pipe/pipe_tupler.h \
+SeqAn-1.4.2/seqan/pipe/pool_base.h \
+SeqAn-1.4.2/seqan/pipe/pool_mapper.h \
+SeqAn-1.4.2/seqan/pipe/pool_sorter.h \
+SeqAn-1.4.2/seqan/platform.h \
+SeqAn-1.4.2/seqan/platform/INFO \
+SeqAn-1.4.2/seqan/platform/platform_gcc.h \
+SeqAn-1.4.2/seqan/platform/platform_icc.h \
+SeqAn-1.4.2/seqan/platform/platform_mingw.h \
+SeqAn-1.4.2/seqan/platform/platform_nvcc.h \
+SeqAn-1.4.2/seqan/platform/platform_pgi.h \
+SeqAn-1.4.2/seqan/platform/platform_solaris.h \
+SeqAn-1.4.2/seqan/platform/platform_windows.h \
+SeqAn-1.4.2/seqan/platform/windows_stdint.h \
+SeqAn-1.4.2/seqan/random/ext_MersenneTwister.h \
+SeqAn-1.4.2/seqan/random.h \
+SeqAn-1.4.2/seqan/random/INFO \
+SeqAn-1.4.2/seqan/random/random_base.h \
+SeqAn-1.4.2/seqan/random/random_beta.h \
+SeqAn-1.4.2/seqan/random/random_beta_kfunc.h \
+SeqAn-1.4.2/seqan/random/random_geometric.h \
+SeqAn-1.4.2/seqan/random/random_lognormal.h \
+SeqAn-1.4.2/seqan/random/random_mt19937.h \
+SeqAn-1.4.2/seqan/random/random_normal.h \
+SeqAn-1.4.2/seqan/random/random_rng_functor.h \
+SeqAn-1.4.2/seqan/random/random_shuffle.h \
+SeqAn-1.4.2/seqan/random/random_uniform.h \
+SeqAn-1.4.2/seqan/score.h \
+SeqAn-1.4.2/seqan/score/INFO \
+SeqAn-1.4.2/seqan/score/score_base.h \
+SeqAn-1.4.2/seqan/score/score_edit.h \
+SeqAn-1.4.2/seqan/score/score_matrix_data.h \
+SeqAn-1.4.2/seqan/score/score_matrix.h \
+SeqAn-1.4.2/seqan/score/score_matrix_io.h \
+SeqAn-1.4.2/seqan/score/score_simple.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_impl.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_profile.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_scout.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_traceback.h \
+SeqAn-1.4.2/seqan/seeds/basic_iter_indirect.h \
+SeqAn-1.4.2/seqan/seeds.h \
+SeqAn-1.4.2/seqan/seeds/INFO \
+SeqAn-1.4.2/seqan/seeds/seeds_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_combination.h \
+SeqAn-1.4.2/seqan/seeds/seeds_extension.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_gusfield.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_chained.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_diagonal.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_non_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_unordered.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_simple.h \
+SeqAn-1.4.2/seqan/seq_io/fai_index.h \
+SeqAn-1.4.2/seqan/seq_io/genomic_region.h \
+SeqAn-1.4.2/seqan/seq_io/guess_stream_format.h \
+SeqAn-1.4.2/seqan/seq_io.h \
+SeqAn-1.4.2/seqan/seq_io/INFO \
+SeqAn-1.4.2/seqan/seq_io/read_embl.h \
+SeqAn-1.4.2/seqan/seq_io/read_fasta_fastq.h \
+SeqAn-1.4.2/seqan/seq_io/read_genbank.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream_impl.h \
+SeqAn-1.4.2/seqan/seq_io/simple_read_fasta.h \
+SeqAn-1.4.2/seqan/seq_io/write_fasta_fastq.h \
+SeqAn-1.4.2/seqan/sequence/adapt_array_pointer.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_list.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_string.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_vector.h \
+SeqAn-1.4.2/seqan/sequence.h \
+SeqAn-1.4.2/seqan/sequence/INFO \
+SeqAn-1.4.2/seqan/sequence/iter_concat_virtual.h \
+SeqAn-1.4.2/seqan/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/INFO \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_sorted_array.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entry.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled_iterator.h \
+SeqAn-1.4.2/seqan/sequence/segment_base.h \
+SeqAn-1.4.2/seqan/sequence/segment_infix.h \
+SeqAn-1.4.2/seqan/sequence/segment_prefix.h \
+SeqAn-1.4.2/seqan/sequence/segment_suffix.h \
+SeqAn-1.4.2/seqan/sequence/segment_utils.h \
+SeqAn-1.4.2/seqan/sequence/sequence_concatenator.h \
+SeqAn-1.4.2/seqan/sequence/sequence_forwards.h \
+SeqAn-1.4.2/seqan/sequence/sequence_interface.h \
+SeqAn-1.4.2/seqan/sequence/sequence_lexical.h \
+SeqAn-1.4.2/seqan/sequence/sequence_shortcuts.h \
+SeqAn-1.4.2/seqan/sequence/string_alloc.h \
+SeqAn-1.4.2/seqan/sequence/string_array.h \
+SeqAn-1.4.2/seqan/sequence/string_base.h \
+SeqAn-1.4.2/seqan/sequence/string_block.h \
+SeqAn-1.4.2/seqan/sequence/string_cstyle.h \
+SeqAn-1.4.2/seqan/sequence/string_packed.h \
+SeqAn-1.4.2/seqan/sequence/string_packed_old.h \
+SeqAn-1.4.2/seqan/sequence/string_set_base.h \
+SeqAn-1.4.2/seqan/sequence/string_set_concat_direct.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_generous.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_tight.h \
+SeqAn-1.4.2/seqan/sequence/string_set_owner.h \
+SeqAn-1.4.2/seqan/store.h \
+SeqAn-1.4.2/seqan/store/INFO \
+SeqAn-1.4.2/seqan/store/store_align.h \
+SeqAn-1.4.2/seqan/store/store_align_intervals.h \
+SeqAn-1.4.2/seqan/store/store_all.h \
+SeqAn-1.4.2/seqan/store/store_annotation.h \
+SeqAn-1.4.2/seqan/store/store_base.h \
+SeqAn-1.4.2/seqan/store/store_contig.h \
+SeqAn-1.4.2/seqan/store/store_intervaltree.h \
+SeqAn-1.4.2/seqan/store/store_io_gff.h \
+SeqAn-1.4.2/seqan/store/store_io.h \
+SeqAn-1.4.2/seqan/store/store_io_sam.h \
+SeqAn-1.4.2/seqan/store/store_io_ucsc.h \
+SeqAn-1.4.2/seqan/store/store_library.h \
+SeqAn-1.4.2/seqan/store/store_matepair.h \
+SeqAn-1.4.2/seqan/store/store_read.h \
+SeqAn-1.4.2/seqan/stream/adapt_cstdio.h \
+SeqAn-1.4.2/seqan/stream/adapt_fstream.h \
+SeqAn-1.4.2/seqan/stream/adapt_iostream.h \
+SeqAn-1.4.2/seqan/stream/adapt_mmap.h \
+SeqAn-1.4.2/seqan/stream/adapt_sstream.h \
+SeqAn-1.4.2/seqan/stream/concept_stream.h \
+SeqAn-1.4.2/seqan/stream/file_stream.h \
+SeqAn-1.4.2/seqan/stream.h \
+SeqAn-1.4.2/seqan/stream/INFO \
+SeqAn-1.4.2/seqan/stream/is.h \
+SeqAn-1.4.2/seqan/stream/lexical_cast.h \
+SeqAn-1.4.2/seqan/stream/read_auto_format.h \
+SeqAn-1.4.2/seqan/stream/read.h \
+SeqAn-1.4.2/seqan/stream/read_sam.h \
+SeqAn-1.4.2/seqan/stream/record_reader_base.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double_mmap.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single_mmap.h \
+SeqAn-1.4.2/seqan/stream/stream_base.h \
+SeqAn-1.4.2/seqan/stream/stream_bgzf.h \
+SeqAn-1.4.2/seqan/stream/stream_bz2_file.h \
+SeqAn-1.4.2/seqan/stream/stream_char_array.h \
+SeqAn-1.4.2/seqan/stream/stream_gz_file.h \
+SeqAn-1.4.2/seqan/stream/stream_put.h \
+SeqAn-1.4.2/seqan/stream/tokenize.h \
+SeqAn-1.4.2/seqan/stream/write.h \
+SeqAn-1.4.2/seqan/system/file_async.h \
+SeqAn-1.4.2/seqan/system/file_directory.h \
+SeqAn-1.4.2/seqan/system/file_forwards.h \
+SeqAn-1.4.2/seqan/system/file_sync.h \
+SeqAn-1.4.2/seqan/system.h \
+SeqAn-1.4.2/seqan/system/INFO \
+SeqAn-1.4.2/seqan/system/system_base.h \
+SeqAn-1.4.2/seqan/system/system_event.h \
+SeqAn-1.4.2/seqan/system/system_forwards.h \
+SeqAn-1.4.2/seqan/system/system_mutex.h \
+SeqAn-1.4.2/seqan/system/system_sema.h \
+SeqAn-1.4.2/seqan/system/system_thread.h \
+SeqAn-1.4.2/seqan/version.h
SAMDIR = ./samtools-0.1.18
SAMLIB = libbam.a
@@ -624,7 +707,6 @@ bin_PROGRAMS = \
tophat_reports \
sam_juncs
-# $(SAMPROG)
bin_SCRIPTS = \
tophat2 \
tophat
@@ -636,10 +718,6 @@ dist_bin_SCRIPTS = \
sra_to_solid \
tophat-fusion-post
-
-#samtools_0_1_18_SOURCES =
-#samtools_0_1_18_LDADD =
-
CLEANFILES = \
tophat2 \
tophat
@@ -647,11 +725,11 @@ CLEANFILES = \
clean-local:
cd $(SAMDIR) && make clean
-tophat2: tophat2.in
- sed -e 's|__PREFIX__|$(prefix)|' tophat2.in > tophat2
+tophat2: tophat2.sh
+ cp tophat2.sh tophat2 && chmod 755 tophat2
tophat: tophat.py
- sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat
+ sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat && chmod 755 tophat
#-- tophat library for linking convienence
noinst_LIBRARIES = $(SAMLIB) libgc.a libtophat.a
@@ -775,3 +853,6 @@ $(SAMPROG): $(SAMLIB)
$(SAMLIB):
cd $(SAMDIR) && make $(SAMPROG) && cp $(SAMLIB) $(SAMPROG) ..
+
+install-data-hook:
+ cp -r intervaltree sortedcontainers $(DESTDIR)$(bindir)
diff --git a/src/Makefile.in b/src/Makefile.in
index fcf9d17..1c9b4d6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -363,7 +363,16 @@ top_srcdir = @top_srcdir@
# - and tophat2.in added
EXTRA_DIST = \
tophat.py \
-tophat2.in \
+tophat2.sh \
+intervaltree/__init__.py \
+intervaltree/interval.py \
+intervaltree/intervaltree.py \
+intervaltree/node.py \
+sortedcontainers/__init__.py \
+sortedcontainers/sorteddict.py \
+sortedcontainers/sortedlist.py \
+sortedcontainers/sortedlistwithkey.py \
+sortedcontainers/sortedset.py \
samtools-0.1.18/AUTHORS \
samtools-0.1.18/COPYING \
samtools-0.1.18/ChangeLog \
@@ -448,520 +457,592 @@ samtools-0.1.18/bcftools/prob1.c \
samtools-0.1.18/bcftools/prob1.h \
samtools-0.1.18/bcftools/vcf.c \
samtools-0.1.18/bcftools/vcfutils.pl \
-SeqAn-1.3/COPYING \
-SeqAn-1.3/README \
-SeqAn-1.3/seqan/chaining/chain_generic.h \
-SeqAn-1.3/seqan/chaining/rt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/score_zero.h \
-SeqAn-1.3/seqan/chaining/geom_distribution.h \
-SeqAn-1.3/seqan/chaining/chain_base.h \
-SeqAn-1.3/seqan/chaining/chaining_generated_forwards.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/skip_element.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_element.h \
-SeqAn-1.3/seqan/chaining/rt_sl_impl.h \
-SeqAn-1.3/seqan/chaining/chain_wrapper_point.h \
-SeqAn-1.3/seqan/chaining/rmt_compl_algos.h \
-SeqAn-1.3/seqan/chaining/rmt_base.h \
-SeqAn-1.3/seqan/chaining/skip_list.h \
-SeqAn-1.3/seqan/chaining/skip_list_iterator.h \
-SeqAn-1.3/seqan/chaining/skip_base_element.h \
-SeqAn-1.3/seqan/chaining/fragment.h \
-SeqAn-1.3/seqan/chaining/skip_pool_alloc.h \
-SeqAn-1.3/seqan/chaining/skip_list_impl.h \
-SeqAn-1.3/seqan/chaining/rt_skip_element.h \
-SeqAn-1.3/seqan/chaining/tree_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rmt_common_algos.h \
-SeqAn-1.3/seqan/chaining/score_manhattan.h \
-SeqAn-1.3/seqan/chaining/score_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rt_impl.h \
-SeqAn-1.3/seqan/chaining/tree_chain.h \
-SeqAn-1.3/seqan/chaining/tree_chain_utils.h \
-SeqAn-1.3/seqan/chaining/skip_list_base.h \
-SeqAn-1.3/seqan/chaining/rt_sl_def_algos.h \
-SeqAn-1.3/seqan/chaining/range_tree.h \
-SeqAn-1.3/seqan/chaining/rmt_def_algos.h \
-SeqAn-1.3/seqan/chaining/chain_point.h \
-SeqAn-1.3/seqan/chaining/rt_base.h \
-SeqAn-1.3/seqan/chaining/chain_meta_fragment.h \
-SeqAn-1.3/seqan/chaining/score_chain.h \
-SeqAn-1.3/seqan/chaining/rt_common_algos.h \
-SeqAn-1.3/seqan/chaining/skip_list_dynamic.h \
-SeqAn-1.3/seqan/chaining/rt_sl_base.h \
-SeqAn-1.3/seqan/chaining/skip_list_type.h \
-SeqAn-1.3/seqan/chaining/range_max_tree.h \
-SeqAn-1.3/seqan/chaining/rt_sl_compl_algos.h \
-SeqAn-1.3/seqan/file/file_format_cgviz.h \
-SeqAn-1.3/seqan/file/stream.h \
-SeqAn-1.3/seqan/file/file_format_embl.h \
-SeqAn-1.3/seqan/file/file_format_fasta.h \
-SeqAn-1.3/seqan/file/string_mmap.h \
-SeqAn-1.3/seqan/file/file_format_raw.h \
-SeqAn-1.3/seqan/file/string_external.h \
-SeqAn-1.3/seqan/file/file_filereader.h \
-SeqAn-1.3/seqan/file/file_cstyle.h \
-SeqAn-1.3/seqan/file/file_page_raid0.h \
-SeqAn-1.3/seqan/file/cstream.h \
-SeqAn-1.3/seqan/file/file_format_guess.h \
-SeqAn-1.3/seqan/file/file_base.h \
-SeqAn-1.3/seqan/file/file_format_mmap.h \
-SeqAn-1.3/seqan/file/file_forwards.h \
-SeqAn-1.3/seqan/file/file_array.h \
-SeqAn-1.3/seqan/file/meta.h \
-SeqAn-1.3/seqan/file/stream_algorithms.h \
-SeqAn-1.3/seqan/file/file_format.h \
-SeqAn-1.3/seqan/file/file_filereaderiterator.h \
-SeqAn-1.3/seqan/file/file_format_genbank.h \
-SeqAn-1.3/seqan/file/file_generated_forwards.h \
-SeqAn-1.3/seqan/file/file_format_fasta_align.h \
-SeqAn-1.3/seqan/file/chunk_collector.h \
-SeqAn-1.3/seqan/file/file_page.h \
-SeqAn-1.3/seqan/seeds.h \
-SeqAn-1.3/seqan/find_motif.h \
-SeqAn-1.3/seqan/LICENSE \
-SeqAn-1.3/seqan/find2/find_approx_find_begin.h \
-SeqAn-1.3/seqan/find2/find_finder_default.h \
-SeqAn-1.3/seqan/find2/find_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_multiple_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_hamming_simple.h \
-SeqAn-1.3/seqan/find2/find_pattern_wild_shiftand.h \
-SeqAn-1.3/seqan/find2/find_approx_dpsearch.h \
-SeqAn-1.3/seqan/find2/find_exact_shiftand.h \
-SeqAn-1.3/seqan/find2/find2_generated_forwards.h \
-SeqAn-1.3/seqan/find2/find_base.h \
-SeqAn-1.3/seqan/platform.h \
-SeqAn-1.3/seqan/sequence_journaled.h \
-SeqAn-1.3/seqan/chaining.h \
-SeqAn-1.3/seqan/score/score_generated_forwards.h \
-SeqAn-1.3/seqan/score/score_matrix_data.h \
-SeqAn-1.3/seqan/score/score_matrix.h \
-SeqAn-1.3/seqan/score/score_simple.h \
-SeqAn-1.3/seqan/score/score_base.h \
-SeqAn-1.3/seqan/score/score_edit.h \
-SeqAn-1.3/seqan/graph_algorithms.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entry.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_sorted_array.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_generated_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
-SeqAn-1.3/seqan/align/gaps_iterator_base.h \
-SeqAn-1.3/seqan/align/gaps_array.h \
-SeqAn-1.3/seqan/align/matrix_base.h \
-SeqAn-1.3/seqan/align/gaps_base.h \
-SeqAn-1.3/seqan/align/align_iterator_base.h \
-SeqAn-1.3/seqan/align/align_algorithms.h \
-SeqAn-1.3/seqan/align/align_hirschberg.h \
-SeqAn-1.3/seqan/align/align_local_dynprog.h \
-SeqAn-1.3/seqan/align/align_cols_base.h \
-SeqAn-1.3/seqan/align/align_generated_forwards.h \
-SeqAn-1.3/seqan/align/align_base.h \
-SeqAn-1.3/seqan/align/gaps_sumlist.h \
-SeqAn-1.3/seqan/align/align_local_dynprog_banded.h \
-SeqAn-1.3/seqan/align/align_dynprog.h \
-SeqAn-1.3/seqan/align/align_myers.h \
-SeqAn-1.3/seqan/align/hirschberg_set.h \
-SeqAn-1.3/seqan/align/align_trace.h \
-SeqAn-1.3/seqan/pipe/pipe_sampler.h \
-SeqAn-1.3/seqan/pipe/pipe_filter.h \
-SeqAn-1.3/seqan/pipe/pool_sorter.h \
-SeqAn-1.3/seqan/pipe/pipe_namer.h \
-SeqAn-1.3/seqan/pipe/pipe_joiner.h \
-SeqAn-1.3/seqan/pipe/pipe_base.h \
-SeqAn-1.3/seqan/pipe/pipe_echoer.h \
-SeqAn-1.3/seqan/pipe/pipe_caster.h \
-SeqAn-1.3/seqan/pipe/pipe_generated_forwards.h \
-SeqAn-1.3/seqan/pipe/pipe_counter.h \
-SeqAn-1.3/seqan/pipe/pool_mapper.h \
-SeqAn-1.3/seqan/pipe/pipe_edit_environment.h \
-SeqAn-1.3/seqan/pipe/pool_base.h \
-SeqAn-1.3/seqan/pipe/pipe_shifter.h \
-SeqAn-1.3/seqan/pipe/pipe_source.h \
-SeqAn-1.3/seqan/pipe/pipe_tupler.h \
-SeqAn-1.3/seqan/pipe/pipe_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_vertex.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_oracle.h \
-SeqAn-1.3/seqan/graph_types/graph_idmanager.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_adjacency.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_automaton.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_trie.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_bfs.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_dfs.h \
-SeqAn-1.3/seqan/graph_types/graph_property.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_fragment.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_outedge.h \
-SeqAn-1.3/seqan/graph_types/graph_utility_parsing.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_undirected.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_hmm.h \
-SeqAn-1.3/seqan/graph_types/graph_base.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_edge.h \
-SeqAn-1.3/seqan/graph_types/graph_edgestump.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_tree.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_wordgraph.h \
-SeqAn-1.3/seqan/graph_types/graph_types_generated_forwards.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_directed.h \
-SeqAn-1.3/seqan/graph_types/graph_drawing.h \
-SeqAn-1.3/seqan/graph_types/graph_interface.h \
-SeqAn-1.3/seqan/file.h \
-SeqAn-1.3/seqan/system.h \
-SeqAn-1.3/seqan/refinement.h \
-SeqAn-1.3/seqan/pipe.h \
-SeqAn-1.3/seqan/system/system_thread.h \
-SeqAn-1.3/seqan/system/system_base.h \
-SeqAn-1.3/seqan/system/system_event.h \
-SeqAn-1.3/seqan/system/file_directory.h \
-SeqAn-1.3/seqan/system/system_mutex.h \
-SeqAn-1.3/seqan/system/file_manual_forwards.h \
-SeqAn-1.3/seqan/system/system_generated_forwards.h \
-SeqAn-1.3/seqan/system/file_sync.h \
-SeqAn-1.3/seqan/system/file_async.h \
-SeqAn-1.3/seqan/system/system_sema.h \
-SeqAn-1.3/seqan/system/system_manual_forwards.h \
-SeqAn-1.3/seqan/misc/edit_environment.h \
-SeqAn-1.3/seqan/misc/misc_parsing.h \
-SeqAn-1.3/seqan/misc/misc_generated_forwards.h \
-SeqAn-1.3/seqan/misc/misc_base.h \
-SeqAn-1.3/seqan/misc/priority_type_heap.h \
-SeqAn-1.3/seqan/misc/priority_type_base.h \
-SeqAn-1.3/seqan/misc/misc_dequeue.h \
-SeqAn-1.3/seqan/misc/misc_set.h \
-SeqAn-1.3/seqan/misc/misc_map.h \
-SeqAn-1.3/seqan/misc/misc_svg.h \
-SeqAn-1.3/seqan/misc/misc_interval_tree.h \
-SeqAn-1.3/seqan/misc/misc_long_word.h \
-SeqAn-1.3/seqan/misc/misc_cmdparser.h \
-SeqAn-1.3/seqan/misc/misc_random.h \
-SeqAn-1.3/seqan/platform/platform_mingw.h \
-SeqAn-1.3/seqan/platform/platform_gcc.h \
-SeqAn-1.3/seqan/platform/platform_windows.h \
-SeqAn-1.3/seqan/platform/platform_solaris.h \
-SeqAn-1.3/seqan/platform/platform_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman.h \
-SeqAn-1.3/seqan/graph_align/graph_align_base.h \
-SeqAn-1.3/seqan/graph_align/graph_align_hirschberg.h \
-SeqAn-1.3/seqan/graph_align/graph_align_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_interface.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_config.h \
-SeqAn-1.3/seqan/parallel/parallel_generated_forwards.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_misc.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_primitives.h \
-SeqAn-1.3/seqan/parallel/parallel_macros.h \
-SeqAn-1.3/seqan/store/store_io_gff.h \
-SeqAn-1.3/seqan/store/store_library.h \
-SeqAn-1.3/seqan/store/store_read.h \
-SeqAn-1.3/seqan/store/store_annotation.h \
-SeqAn-1.3/seqan/store/store_intervaltree.h \
-SeqAn-1.3/seqan/store/store_io_ucsc.h \
-SeqAn-1.3/seqan/store/store_all.h \
-SeqAn-1.3/seqan/store/store_matepair.h \
-SeqAn-1.3/seqan/store/store_align_intervals.h \
-SeqAn-1.3/seqan/store/store_io.h \
-SeqAn-1.3/seqan/store/store_io_sam.h \
-SeqAn-1.3/seqan/store/store_align.h \
-SeqAn-1.3/seqan/store/store_io_bam.h \
-SeqAn-1.3/seqan/store/store_contig.h \
-SeqAn-1.3/seqan/store/store_generated_forwards.h \
-SeqAn-1.3/seqan/store/store_base.h \
-SeqAn-1.3/seqan/align.h \
-SeqAn-1.3/seqan/modifier/modifier_string.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet_expansion.h \
-SeqAn-1.3/seqan/modifier/modifier_shortcuts.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet.h \
-SeqAn-1.3/seqan/modifier/modifier_iterator.h \
-SeqAn-1.3/seqan/modifier/modifier_reverse.h \
-SeqAn-1.3/seqan/modifier/modifier_generated_forwards.h \
-SeqAn-1.3/seqan/modifier/modifier_view.h \
-SeqAn-1.3/seqan/modifier/modifier_functors.h \
-SeqAn-1.3/seqan/seeds2.h \
-SeqAn-1.3/seqan/index/index_sa_btree.h \
-SeqAn-1.3/seqan/index/find_quasar.h \
-SeqAn-1.3/seqan/index/index_esa_algs.h \
-SeqAn-1.3/seqan/index/index_skew7.h \
-SeqAn-1.3/seqan/index/index_pizzachili.h \
-SeqAn-1.3/seqan/index/index_sa_lss.h \
-SeqAn-1.3/seqan/index/pump_extender7.h \
-SeqAn-1.3/seqan/index/index_shawarma.h \
-SeqAn-1.3/seqan/index/find_index_approx.h \
-SeqAn-1.3/seqan/index/index_lcp.h \
-SeqAn-1.3/seqan/index/find_swift.h \
-SeqAn-1.3/seqan/index/shape_threshold.h \
-SeqAn-1.3/seqan/index/pizzachili_api.h \
-SeqAn-1.3/seqan/index/index_sa_mm.h \
-SeqAn-1.3/seqan/index/index_esa_stree.h \
-SeqAn-1.3/seqan/index/index_qgram.h \
-SeqAn-1.3/seqan/index/pump_extender3.h \
-SeqAn-1.3/seqan/index/shape_onegapped.h \
-SeqAn-1.3/seqan/index/find_index_qgram.h \
-SeqAn-1.3/seqan/index/index_skew3.h \
-SeqAn-1.3/seqan/index/index_childtab.h \
-SeqAn-1.3/seqan/index/pipe_merger7.h \
-SeqAn-1.3/seqan/index/pipe_merger3.h \
-SeqAn-1.3/seqan/index/repeat_base.h \
-SeqAn-1.3/seqan/index/index_pizzachili_find.h \
-SeqAn-1.3/seqan/index/index_sa_qsort.h \
-SeqAn-1.3/seqan/index/index_shims.h \
-SeqAn-1.3/seqan/index/index_manual_forwards.h \
-SeqAn-1.3/seqan/index/shape_base.h \
-SeqAn-1.3/seqan/index/shape_predefined.h \
-SeqAn-1.3/seqan/index/index_pizzachili_string.h \
-SeqAn-1.3/seqan/index/index_generated_forwards.h \
-SeqAn-1.3/seqan/index/find_index_esa.h \
-SeqAn-1.3/seqan/index/pump_separator7.h \
-SeqAn-1.3/seqan/index/index_esa_base.h \
-SeqAn-1.3/seqan/index/radix.h \
-SeqAn-1.3/seqan/index/index_skew7_multi.h \
-SeqAn-1.3/seqan/index/index_esa_algs_multi.h \
-SeqAn-1.3/seqan/index/index_base.h \
-SeqAn-1.3/seqan/index/shape_gapped.h \
-SeqAn-1.3/seqan/index/index_lcp_tree.h \
-SeqAn-1.3/seqan/index/index_esa_drawing.h \
-SeqAn-1.3/seqan/index/find_index.h \
-SeqAn-1.3/seqan/index/pump_lcp_core.h \
-SeqAn-1.3/seqan/index/index_dfi.h \
-SeqAn-1.3/seqan/index/index_sa_bwtwalk.h \
-SeqAn-1.3/seqan/index/index_qgram_openaddressing.h \
-SeqAn-1.3/seqan/index/index_bwt.h \
-SeqAn-1.3/seqan/index/index_wotd.h \
-SeqAn-1.3/seqan/statistics/statistics_base.h \
-SeqAn-1.3/seqan/statistics/statistics_markov_model.h \
-SeqAn-1.3/seqan/statistics/statistics_generated_forwards.h \
-SeqAn-1.3/seqan/score.h \
-SeqAn-1.3/seqan/sequence.h \
-SeqAn-1.3/seqan/parallel.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithms_generated_forwards.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_hmm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_lis_his.h \
-SeqAn-1.3/seqan/blast.h \
-SeqAn-1.3/seqan/store.h \
-SeqAn-1.3/seqan/graph_align.h \
-SeqAn-1.3/seqan/random/random_lognormal.h \
-SeqAn-1.3/seqan/random/ext_MersenneTwister.h \
-SeqAn-1.3/seqan/random/random_generated_forwards.h \
-SeqAn-1.3/seqan/random/random_rng_functor.h \
-SeqAn-1.3/seqan/random/random_base.h \
-SeqAn-1.3/seqan/random/random_uniform.h \
-SeqAn-1.3/seqan/random/random_shuffle.h \
-SeqAn-1.3/seqan/random/random_normal.h \
-SeqAn-1.3/seqan/random/random_geometric.h \
-SeqAn-1.3/seqan/random/random_mt19937.h \
-SeqAn-1.3/seqan/basic.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_progressive.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_distance.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_io.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_kmer.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_refinement.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_msa.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
-SeqAn-1.3/seqan/graph_msa/graph_msa_generated_forwards.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_library.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_base.h \
-SeqAn-1.3/seqan/basic/basic_sse2.h \
-SeqAn-1.3/seqan/basic/basic_forwards.h \
-SeqAn-1.3/seqan/basic/basic_testing.h \
-SeqAn-1.3/seqan/basic/basic_counted_ptr.h \
-SeqAn-1.3/seqan/basic/basic_iterator_base.h \
-SeqAn-1.3/seqan/basic/basic_pointer.h \
-SeqAn-1.3/seqan/basic/basic_allocator_chunkpool.h \
-SeqAn-1.3/seqan/basic/basic_parallelism.h \
-SeqAn-1.3/seqan/basic/basic_allocator_singlepool.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adaptor.h \
-SeqAn-1.3/seqan/basic/basic_profile.h \
-SeqAn-1.3/seqan/basic/basic_tag.h \
-SeqAn-1.3/seqan/basic/basic_compare.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface.h \
-SeqAn-1.3/seqan/basic/basic_iterator_simple.h \
-SeqAn-1.3/seqan/basic/basic_definition.h \
-SeqAn-1.3/seqan/basic/basic_operator.h \
-SeqAn-1.3/seqan/basic/basic_holder_dynamic.h \
-SeqAn-1.3/seqan/basic/basic_allocator_multipool.h \
-SeqAn-1.3/seqan/basic/basic_proxy.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple_tabs.h \
-SeqAn-1.3/seqan/basic/basic_metaprogramming.h \
-SeqAn-1.3/seqan/basic/basic_host.h \
-SeqAn-1.3/seqan/basic/basic_allocator_to_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_interface.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface2.h \
-SeqAn-1.3/seqan/basic/basic_logvalue.h \
-SeqAn-1.3/seqan/basic/basic_volatile_ptr.h \
-SeqAn-1.3/seqan/basic/basic_debug.h \
-SeqAn-1.3/seqan/basic/basic_profchar.h \
-SeqAn-1.3/seqan/basic/basic_aggregates.h \
-SeqAn-1.3/seqan/basic/basic_transport.h \
-SeqAn-1.3/seqan/basic/basic_holder.h \
-SeqAn-1.3/seqan/basic/basic_converter.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple.h \
-SeqAn-1.3/seqan/basic/basic_type.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adapt_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_simple.h \
-SeqAn-1.3/seqan/basic/basic_iterator.h \
-SeqAn-1.3/seqan/basic/basic_generated_forwards.h \
-SeqAn-1.3/seqan/basic/basic_iterator_position.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_trait_basic.h \
-SeqAn-1.3/seqan/sequence/sequence_forwards.h \
-SeqAn-1.3/seqan/sequence/segment_infix.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_tight.h \
-SeqAn-1.3/seqan/sequence/segment_base.h \
-SeqAn-1.3/seqan/sequence/sequence_lexical.h \
-SeqAn-1.3/seqan/sequence/string_cstyle.h \
-SeqAn-1.3/seqan/sequence/sequence_concatenator.h \
-SeqAn-1.3/seqan/sequence/string_packed.h \
-SeqAn-1.3/seqan/sequence/sequence_stream.h \
-SeqAn-1.3/seqan/sequence/sequence_shortcuts.h \
-SeqAn-1.3/seqan/sequence/adapt_std_list.h \
-SeqAn-1.3/seqan/sequence/string_base.h \
-SeqAn-1.3/seqan/sequence/string_set_owner.h \
-SeqAn-1.3/seqan/sequence/adapt_std_string.h \
-SeqAn-1.3/seqan/sequence/sequence_generated_forwards.h \
-SeqAn-1.3/seqan/sequence/string_set_concat_direct.h \
-SeqAn-1.3/seqan/sequence/sequence_interface.h \
-SeqAn-1.3/seqan/sequence/adapt_array_pointer.h \
-SeqAn-1.3/seqan/sequence/segment_suffix.h \
-SeqAn-1.3/seqan/sequence/string_array.h \
-SeqAn-1.3/seqan/sequence/iter_concat_virtual.h \
-SeqAn-1.3/seqan/sequence/segment_prefix.h \
-SeqAn-1.3/seqan/sequence/string_block.h \
-SeqAn-1.3/seqan/sequence/string_set_base.h \
-SeqAn-1.3/seqan/sequence/adapt_std_vector.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_generous.h \
-SeqAn-1.3/seqan/sequence/string_alloc.h \
-SeqAn-1.3/seqan/modifier.h \
-SeqAn-1.3/seqan/random.h \
-SeqAn-1.3/seqan/statistics.h \
-SeqAn-1.3/seqan/consensus.h \
-SeqAn-1.3/seqan/find.h \
-SeqAn-1.3/seqan/find2.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_inexact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_fragment.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_annotation.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_align.h \
-SeqAn-1.3/seqan/refinement/refinement_generated_forwards.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_scoring.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact_iterative.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align_adapt.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_aligngraph.h \
-SeqAn-1.3/seqan/seeds/global_seed_chain.h \
-SeqAn-1.3/seqan/seeds/seedSet_score.h \
-SeqAn-1.3/seqan/seeds/seeds_generated_forwards.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align_affine.h \
-SeqAn-1.3/seqan/seeds/banded_align.h \
-SeqAn-1.3/seqan/seeds/memoryManager_int.h \
-SeqAn-1.3/seqan/seeds/seedHandlingTags.h \
-SeqAn-1.3/seqan/seeds/seedSet_iterator.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align.h \
-SeqAn-1.3/seqan/seeds/seed_multi.h \
-SeqAn-1.3/seqan/seeds/seedSet_base.h \
-SeqAn-1.3/seqan/seeds/propertyMap.h \
-SeqAn-1.3/seqan/seeds/memoryManager_base.h \
-SeqAn-1.3/seqan/seeds/seed_base.h \
-SeqAn-1.3/seqan/graph_msa.h \
-SeqAn-1.3/seqan/consensus/consensus_score.h \
-SeqAn-1.3/seqan/consensus/consensus_base.h \
-SeqAn-1.3/seqan/consensus/consensus_generated_forwards.h \
-SeqAn-1.3/seqan/consensus/consensus_realign.h \
-SeqAn-1.3/seqan/consensus/consensus_library.h \
-SeqAn-1.3/seqan/map/map_generated_forwards.h \
-SeqAn-1.3/seqan/map/map_base.h \
-SeqAn-1.3/seqan/map/map_chooser.h \
-SeqAn-1.3/seqan/map/map_vector.h \
-SeqAn-1.3/seqan/map/sumlist_mini.h \
-SeqAn-1.3/seqan/map/map_adapter_stl.h \
-SeqAn-1.3/seqan/map/sumlist.h \
-SeqAn-1.3/seqan/map/map_skiplist.h \
-SeqAn-1.3/seqan/map/sumlist_skip.h \
-SeqAn-1.3/seqan/blast/blast_stream_report.h \
-SeqAn-1.3/seqan/blast/blast_run.h \
-SeqAn-1.3/seqan/blast/blast_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hsp.h \
-SeqAn-1.3/seqan/blast/blast_base.h \
-SeqAn-1.3/seqan/blast/blast_hit.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit.h \
-SeqAn-1.3/seqan/blast/blast_iterator.h \
-SeqAn-1.3/seqan/blast/blast_parsing.h \
-SeqAn-1.3/seqan/blast/blast_report.h \
-SeqAn-1.3/seqan/blast/blast_generated_forwards.h \
-SeqAn-1.3/seqan/blast/blast_stream_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hit_iterator.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_base.h \
-SeqAn-1.3/seqan/seeds2/seeds_extension.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_unordered.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_base.h \
-SeqAn-1.3/seqan/seeds2/seeds2_generated_forwards.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_diagonal.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_simple.h \
-SeqAn-1.3/seqan/seeds2/seeds_base.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_combination.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_non_scored.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_linear.h \
-SeqAn-1.3/seqan/seeds2/align_chain_banded.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_linear.h \
-SeqAn-1.3/seqan/seeds2/basic_iter_indirect.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_gusfield.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_chained.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_scored.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_base.h \
-SeqAn-1.3/seqan/map.h \
-SeqAn-1.3/seqan/find/find_pattern_base.h \
-SeqAn-1.3/seqan/find/find_multiple_shiftand.h \
-SeqAn-1.3/seqan/find/find_generated_forwards.h \
-SeqAn-1.3/seqan/find/find_horspool.h \
-SeqAn-1.3/seqan/find/find_abndm.h \
-SeqAn-1.3/seqan/find/find_score.h \
-SeqAn-1.3/seqan/find/find_set_horspool.h \
-SeqAn-1.3/seqan/find/find_wild_shiftand.h \
-SeqAn-1.3/seqan/find/find_hamming_simple.h \
-SeqAn-1.3/seqan/find/find_shiftand.h \
-SeqAn-1.3/seqan/find/find_begin.h \
-SeqAn-1.3/seqan/find/find_shiftor.h \
-SeqAn-1.3/seqan/find/find_wumanber.h \
-SeqAn-1.3/seqan/find/find_multi.h \
-SeqAn-1.3/seqan/find/find_simple.h \
-SeqAn-1.3/seqan/find/find_bndm.h \
-SeqAn-1.3/seqan/find/find_pex.h \
-SeqAn-1.3/seqan/find/find_bom.h \
-SeqAn-1.3/seqan/find/find_ahocorasick.h \
-SeqAn-1.3/seqan/find/find_multiple_bfam.h \
-SeqAn-1.3/seqan/find/find_myers_ukkonen.h \
-SeqAn-1.3/seqan/find/find_base.h \
-SeqAn-1.3/seqan/index.h \
-SeqAn-1.3/seqan/graph_types.h \
-SeqAn-1.3/seqan/find_motif/profile.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pmsp.h \
-SeqAn-1.3/seqan/find_motif/sequence_model_types.h \
-SeqAn-1.3/seqan/find_motif/find_motif_base.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_p.h \
-SeqAn-1.3/seqan/find_motif/find_motif_epatternbranching.h \
-SeqAn-1.3/seqan/find_motif/find_motif_projection.h \
-SeqAn-1.3/seqan/find_motif/find_motif_generated_forwards.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_c.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_base.h \
-SeqAn-1.3/seqan/find_motif/em_algorithm.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pms1.h \
-SeqAn-1.3/seqan/find_motif/frequency_distribution.h \
-SeqAn-1.3/seqan.h
+SeqAn-1.4.2/LICENSE \
+SeqAn-1.4.2/README.rst \
+SeqAn-1.4.2/seqan/align/align_base.h \
+SeqAn-1.4.2/seqan/align/align_cols.h \
+SeqAn-1.4.2/seqan/align/align_config.h \
+SeqAn-1.4.2/seqan/align/align_iterator_base.h \
+SeqAn-1.4.2/seqan/align/alignment_algorithm_tags.h \
+SeqAn-1.4.2/seqan/align/alignment_operations.h \
+SeqAn-1.4.2/seqan/align/align_metafunctions.h \
+SeqAn-1.4.2/seqan/align/align_traceback.h \
+SeqAn-1.4.2/seqan/align/dp_algorithm_impl.h \
+SeqAn-1.4.2/seqan/align/dp_band.h \
+SeqAn-1.4.2/seqan/align/dp_cell_affine.h \
+SeqAn-1.4.2/seqan/align/dp_cell.h \
+SeqAn-1.4.2/seqan/align/dp_cell_linear.h \
+SeqAn-1.4.2/seqan/align/dp_formula_affine.h \
+SeqAn-1.4.2/seqan/align/dp_formula.h \
+SeqAn-1.4.2/seqan/align/dp_formula_linear.h \
+SeqAn-1.4.2/seqan/align/dp_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_trace_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_meta_info.h \
+SeqAn-1.4.2/seqan/align/dp_profile.h \
+SeqAn-1.4.2/seqan/align/dp_scout.h \
+SeqAn-1.4.2/seqan/align/dp_setup.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_adaptor.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_impl.h \
+SeqAn-1.4.2/seqan/align/dp_trace_segment.h \
+SeqAn-1.4.2/seqan/align/evaluate_alignment.h \
+SeqAn-1.4.2/seqan/align/gap_anchor.h \
+SeqAn-1.4.2/seqan/align/gapped_value_type.h \
+SeqAn-1.4.2/seqan/align/gaps_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_array.h \
+SeqAn-1.4.2/seqan/align/gaps_base.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_array.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_base.h \
+SeqAn-1.4.2/seqan/align/global_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/global_alignment_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_specialized.h \
+SeqAn-1.4.2/seqan/align/global_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align.h \
+SeqAn-1.4.2/seqan/align/INFO \
+SeqAn-1.4.2/seqan/align/local_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_banded_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/matrix_base.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_argument.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_ctd_support.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_exceptions.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_option.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_type_support.h \
+SeqAn-1.4.2/seqan/arg_parse/argument_parser.h \
+SeqAn-1.4.2/seqan/arg_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/INFO \
+SeqAn-1.4.2/seqan/arg_parse/tool_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/xml_support.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record_util.h \
+SeqAn-1.4.2/seqan/bam_io/bam_header_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_bai.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_base.h \
+SeqAn-1.4.2/seqan/bam_io/bam_io_context.h \
+SeqAn-1.4.2/seqan/bam_io/bam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/bam_sam_conversion.h \
+SeqAn-1.4.2/seqan/bam_io/bam_stream.h \
+SeqAn-1.4.2/seqan/bam_io/bam_tags_dict.h \
+SeqAn-1.4.2/seqan/bam_io/bam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/cigar.h \
+SeqAn-1.4.2/seqan/bam_io.h \
+SeqAn-1.4.2/seqan/bam_io/INFO \
+SeqAn-1.4.2/seqan/bam_io/read_bam.h \
+SeqAn-1.4.2/seqan/bam_io/read_sam.h \
+SeqAn-1.4.2/seqan/bam_io/sam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/sam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/write_bam.h \
+SeqAn-1.4.2/seqan/bam_io/write_sam.h \
+SeqAn-1.4.2/seqan/bam_io/xam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/xam_writer.h \
+SeqAn-1.4.2/seqan/basic/aggregate_concept.h \
+SeqAn-1.4.2/seqan/basic/allocator_chunkpool.h \
+SeqAn-1.4.2/seqan/basic/allocator_interface.h \
+SeqAn-1.4.2/seqan/basic/allocator_multipool.h \
+SeqAn-1.4.2/seqan/basic/allocator_simple.h \
+SeqAn-1.4.2/seqan/basic/allocator_singlepool.h \
+SeqAn-1.4.2/seqan/basic/allocator_to_std.h \
+SeqAn-1.4.2/seqan/basic/alphabet_adapt_builtins.h \
+SeqAn-1.4.2/seqan/basic/alphabet_bio.h \
+SeqAn-1.4.2/seqan/basic/alphabet_concept.h \
+SeqAn-1.4.2/seqan/basic/alphabet_math.h \
+SeqAn-1.4.2/seqan/basic/alphabet_profile.h \
+SeqAn-1.4.2/seqan/basic/alphabet_qualities.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_funcs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_tabs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_simple_type.h \
+SeqAn-1.4.2/seqan/basic/alphabet_storage.h \
+SeqAn-1.4.2/seqan/basic/array_construct_destruct.h \
+SeqAn-1.4.2/seqan/basic/basic_aggregate.h \
+SeqAn-1.4.2/seqan/basic/basic_allocator.h \
+SeqAn-1.4.2/seqan/basic/basic_alphabet.h \
+SeqAn-1.4.2/seqan/basic/basic_concept.h \
+SeqAn-1.4.2/seqan/basic/basic_container.h \
+SeqAn-1.4.2/seqan/basic/basic_debug.h \
+SeqAn-1.4.2/seqan/basic/basic_exception.h \
+SeqAn-1.4.2/seqan/basic/basic_fundamental.h \
+SeqAn-1.4.2/seqan/basic/basic_iterator.h \
+SeqAn-1.4.2/seqan/basic/basic_math.h \
+SeqAn-1.4.2/seqan/basic/basic_metaprogramming.h \
+SeqAn-1.4.2/seqan/basic/basic_parallelism.h \
+SeqAn-1.4.2/seqan/basic/basic_proxy.h \
+SeqAn-1.4.2/seqan/basic/basic_smart_pointer.h \
+SeqAn-1.4.2/seqan/basic/basic_tangle.h \
+SeqAn-1.4.2/seqan/basic/basic_type.h \
+SeqAn-1.4.2/seqan/basic/boost_preprocessor_subset.h \
+SeqAn-1.4.2/seqan/basic/builtin_functions.h \
+SeqAn-1.4.2/seqan/basic/concept_checking.h \
+SeqAn-1.4.2/seqan/basic/container_concept.h \
+SeqAn-1.4.2/seqan/basic/debug_helper.h \
+SeqAn-1.4.2/seqan/basic/debug_test_system.h \
+SeqAn-1.4.2/seqan/basic/fundamental_comparison.h \
+SeqAn-1.4.2/seqan/basic/fundamental_concepts.h \
+SeqAn-1.4.2/seqan/basic/fundamental_conversion.h \
+SeqAn-1.4.2/seqan/basic/fundamental_metafunctions.h \
+SeqAn-1.4.2/seqan/basic/fundamental_tags.h \
+SeqAn-1.4.2/seqan/basic/fundamental_transport.h \
+SeqAn-1.4.2/seqan/basic.h \
+SeqAn-1.4.2/seqan/basic/holder_base.h \
+SeqAn-1.4.2/seqan/basic/holder_simple.h \
+SeqAn-1.4.2/seqan/basic/holder_tristate.h \
+SeqAn-1.4.2/seqan/basic/hosted_type_interface.h \
+SeqAn-1.4.2/seqan/basic/INFO \
+SeqAn-1.4.2/seqan/basic/iterator_adaptor.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_pointer.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_std.h \
+SeqAn-1.4.2/seqan/basic/iterator_base.h \
+SeqAn-1.4.2/seqan/basic/iterator_concept.h \
+SeqAn-1.4.2/seqan/basic/iterator_interface.h \
+SeqAn-1.4.2/seqan/basic/iterator_position.h \
+SeqAn-1.4.2/seqan/basic/macro_deprecated.h \
+SeqAn-1.4.2/seqan/basic/math_functions.h \
+SeqAn-1.4.2/seqan/basic/math_log_space_value.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_control.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_enable_if.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_logic.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_math.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_type.h \
+SeqAn-1.4.2/seqan/basic/pair_base.h \
+SeqAn-1.4.2/seqan/basic/pair_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/pair_packed.h \
+SeqAn-1.4.2/seqan/basic/profiling.h \
+SeqAn-1.4.2/seqan/basic/proxy_base.h \
+SeqAn-1.4.2/seqan/basic/proxy_iterator.h \
+SeqAn-1.4.2/seqan/basic/test_system.h \
+SeqAn-1.4.2/seqan/basic/triple_base.h \
+SeqAn-1.4.2/seqan/basic/triple_packed.h \
+SeqAn-1.4.2/seqan/basic/tuple_base.h \
+SeqAn-1.4.2/seqan/basic/tuple_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/volatile_ptr.h \
+SeqAn-1.4.2/seqan/consensus/consensus_base.h \
+SeqAn-1.4.2/seqan/consensus/consensus_library.h \
+SeqAn-1.4.2/seqan/consensus/consensus_realign.h \
+SeqAn-1.4.2/seqan/consensus/consensus_score.h \
+SeqAn-1.4.2/seqan/consensus.h \
+SeqAn-1.4.2/seqan/consensus/INFO \
+SeqAn-1.4.2/seqan/file/chunk_collector.h \
+SeqAn-1.4.2/seqan/file/cstream.h \
+SeqAn-1.4.2/seqan/file/file_base.h \
+SeqAn-1.4.2/seqan/file/file_cstyle.h \
+SeqAn-1.4.2/seqan/file/file_filereader.h \
+SeqAn-1.4.2/seqan/file/file_filereaderiterator.h \
+SeqAn-1.4.2/seqan/file/file_format_cgviz.h \
+SeqAn-1.4.2/seqan/file/file_format_embl.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta_align.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta.h \
+SeqAn-1.4.2/seqan/file/file_format_genbank.h \
+SeqAn-1.4.2/seqan/file/file_format_guess.h \
+SeqAn-1.4.2/seqan/file/file_format.h \
+SeqAn-1.4.2/seqan/file/file_format_mmap.h \
+SeqAn-1.4.2/seqan/file/file_format_raw.h \
+SeqAn-1.4.2/seqan/file/file_forwards.h \
+SeqAn-1.4.2/seqan/file/file_interface.h \
+SeqAn-1.4.2/seqan/file/file_mapping.h \
+SeqAn-1.4.2/seqan/file/file_page.h \
+SeqAn-1.4.2/seqan/file.h \
+SeqAn-1.4.2/seqan/file/INFO \
+SeqAn-1.4.2/seqan/file/meta.h \
+SeqAn-1.4.2/seqan/file/stream_algorithms.h \
+SeqAn-1.4.2/seqan/file/stream.h \
+SeqAn-1.4.2/seqan/file/string_external.h \
+SeqAn-1.4.2/seqan/file/string_mmap.h \
+SeqAn-1.4.2/seqan/find/find_abndm.h \
+SeqAn-1.4.2/seqan/find/find_ahocorasick.h \
+SeqAn-1.4.2/seqan/find/find_base.h \
+SeqAn-1.4.2/seqan/find/find_begin.h \
+SeqAn-1.4.2/seqan/find/find_bndm.h \
+SeqAn-1.4.2/seqan/find/find_bom.h \
+SeqAn-1.4.2/seqan/find/find_hamming_simple.h \
+SeqAn-1.4.2/seqan/find/find_horspool.h \
+SeqAn-1.4.2/seqan/find/find_multi.h \
+SeqAn-1.4.2/seqan/find/find_multiple_bfam.h \
+SeqAn-1.4.2/seqan/find/find_multiple_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_myers_ukkonen.h \
+SeqAn-1.4.2/seqan/find/find_pattern_base.h \
+SeqAn-1.4.2/seqan/find/find_pex.h \
+SeqAn-1.4.2/seqan/find/find_score.h \
+SeqAn-1.4.2/seqan/find/find_set_horspool.h \
+SeqAn-1.4.2/seqan/find/find_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_shiftor.h \
+SeqAn-1.4.2/seqan/find/find_simple.h \
+SeqAn-1.4.2/seqan/find/find_wild_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_wumanber.h \
+SeqAn-1.4.2/seqan/find.h \
+SeqAn-1.4.2/seqan/find/INFO \
+SeqAn-1.4.2/seqan/gff_io/gff_io_base.h \
+SeqAn-1.4.2/seqan/gff_io/gff_io_context.h \
+SeqAn-1.4.2/seqan/gff_io/gff_stream.h \
+SeqAn-1.4.2/seqan/gff_io.h \
+SeqAn-1.4.2/seqan/gff_io/INFO \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_hmm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_lis_his.h \
+SeqAn-1.4.2/seqan/graph_algorithms.h \
+SeqAn-1.4.2/seqan/graph_algorithms/INFO \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_aligngraph.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_align.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_annotation.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact_iterative.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_fragment.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_inexact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_scoring.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align_adapt.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align.h \
+SeqAn-1.4.2/seqan/graph_align.h \
+SeqAn-1.4.2/seqan/graph_align/INFO \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_base.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_distance.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_io.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_kmer.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_library.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_progressive.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_refinement.h \
+SeqAn-1.4.2/seqan/graph_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/INFO \
+SeqAn-1.4.2/seqan/graph_types/graph_base.h \
+SeqAn-1.4.2/seqan/graph_types/graph_drawing.h \
+SeqAn-1.4.2/seqan/graph_types/graph_edgestump.h \
+SeqAn-1.4.2/seqan/graph_types/graph_idmanager.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_automaton.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_directed.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_fragment.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_hmm.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_oracle.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_tree.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_trie.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_undirected.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_wordgraph.h \
+SeqAn-1.4.2/seqan/graph_types/graph_interface.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_adjacency.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_bfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_dfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_edge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_outedge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_vertex.h \
+SeqAn-1.4.2/seqan/graph_types/graph_property.h \
+SeqAn-1.4.2/seqan/graph_types/graph_utility_parsing.h \
+SeqAn-1.4.2/seqan/graph_types.h \
+SeqAn-1.4.2/seqan/graph_types/INFO \
+SeqAn-1.4.2/seqan/index/find_index_approx.h \
+SeqAn-1.4.2/seqan/index/find_index_esa.h \
+SeqAn-1.4.2/seqan/index/find_index.h \
+SeqAn-1.4.2/seqan/index/find_index_qgram.h \
+SeqAn-1.4.2/seqan/index/find_pigeonhole.h \
+SeqAn-1.4.2/seqan/index/find_quasar.h \
+SeqAn-1.4.2/seqan/index/find_swift.h \
+SeqAn-1.4.2/seqan/index.h \
+SeqAn-1.4.2/seqan/index/index_base.h \
+SeqAn-1.4.2/seqan/index/index_bwt.h \
+SeqAn-1.4.2/seqan/index/index_childtab.h \
+SeqAn-1.4.2/seqan/index/index_dfi.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs_multi.h \
+SeqAn-1.4.2/seqan/index/index_esa_base.h \
+SeqAn-1.4.2/seqan/index/index_esa_drawing.h \
+SeqAn-1.4.2/seqan/index/index_esa_stree.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_doc.h \
+SeqAn-1.4.2/seqan/index/index_fm_dox.h \
+SeqAn-1.4.2/seqan/index/index_fm.h \
+SeqAn-1.4.2/seqan/index/index_fm_lf_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_prefix_sum_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_bms.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_wt.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_sentinel_rank_dictionary.h \
+SeqAn-1.4.2/seqan/index/index_fm_sparse_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_stree.h \
+SeqAn-1.4.2/seqan/index/index_forwards.h \
+SeqAn-1.4.2/seqan/index/index_lcp.h \
+SeqAn-1.4.2/seqan/index/index_lcp_tree.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_find.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_string.h \
+SeqAn-1.4.2/seqan/index/index_qgram.h \
+SeqAn-1.4.2/seqan/index/index_qgram_openaddressing.h \
+SeqAn-1.4.2/seqan/index/index_sa_btree.h \
+SeqAn-1.4.2/seqan/index/index_sa_bwtwalk.h \
+SeqAn-1.4.2/seqan/index/index_sa_lss.h \
+SeqAn-1.4.2/seqan/index/index_sa_mm.h \
+SeqAn-1.4.2/seqan/index/index_sa_qsort.h \
+SeqAn-1.4.2/seqan/index/index_shawarma.h \
+SeqAn-1.4.2/seqan/index/index_shims.h \
+SeqAn-1.4.2/seqan/index/index_skew3.h \
+SeqAn-1.4.2/seqan/index/index_skew7.h \
+SeqAn-1.4.2/seqan/index/index_skew7_multi.h \
+SeqAn-1.4.2/seqan/index/index_wotd.h \
+SeqAn-1.4.2/seqan/index/INFO \
+SeqAn-1.4.2/seqan/index/pipe_merger3.h \
+SeqAn-1.4.2/seqan/index/pipe_merger7.h \
+SeqAn-1.4.2/seqan/index/pizzachili_api.h \
+SeqAn-1.4.2/seqan/index/pump_extender3.h \
+SeqAn-1.4.2/seqan/index/pump_extender7.h \
+SeqAn-1.4.2/seqan/index/pump_lcp_core.h \
+SeqAn-1.4.2/seqan/index/pump_separator7.h \
+SeqAn-1.4.2/seqan/index/radix.h \
+SeqAn-1.4.2/seqan/index/repeat_base.h \
+SeqAn-1.4.2/seqan/index/shape_base.h \
+SeqAn-1.4.2/seqan/index/shape_gapped.h \
+SeqAn-1.4.2/seqan/index/shape_onegapped.h \
+SeqAn-1.4.2/seqan/index/shape_predefined.h \
+SeqAn-1.4.2/seqan/index/shape_threshold.h \
+SeqAn-1.4.2/seqan/LICENSE \
+SeqAn-1.4.2/seqan/map.h \
+SeqAn-1.4.2/seqan/map/INFO \
+SeqAn-1.4.2/seqan/map/map_adapter_stl.h \
+SeqAn-1.4.2/seqan/map/map_base.h \
+SeqAn-1.4.2/seqan/map/map_chooser.h \
+SeqAn-1.4.2/seqan/map/map_skiplist.h \
+SeqAn-1.4.2/seqan/map/map_vector.h \
+SeqAn-1.4.2/seqan/map/sumlist.h \
+SeqAn-1.4.2/seqan/map/sumlist_mini.h \
+SeqAn-1.4.2/seqan/map/sumlist_skip.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdoption.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_ctd_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_parse.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_type_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/INFO \
+SeqAn-1.4.2/seqan/misc/edit_environment.h \
+SeqAn-1.4.2/seqan/misc/INFO \
+SeqAn-1.4.2/seqan/misc/misc_accumulators.h \
+SeqAn-1.4.2/seqan/misc/misc_base.h \
+SeqAn-1.4.2/seqan/misc/misc_bit_twiddling.h \
+SeqAn-1.4.2/seqan/misc/misc_cmdparser.h \
+SeqAn-1.4.2/seqan/misc/misc_dequeue.h \
+SeqAn-1.4.2/seqan/misc/misc_interval_tree.h \
+SeqAn-1.4.2/seqan/misc/misc_map.h \
+SeqAn-1.4.2/seqan/misc/misc_memset.h \
+SeqAn-1.4.2/seqan/misc/misc_name_store_cache.h \
+SeqAn-1.4.2/seqan/misc/misc_parsing.h \
+SeqAn-1.4.2/seqan/misc/misc_set.h \
+SeqAn-1.4.2/seqan/misc/misc_sse2.h \
+SeqAn-1.4.2/seqan/misc/misc_svg.h \
+SeqAn-1.4.2/seqan/misc/misc_terminal.h \
+SeqAn-1.4.2/seqan/misc/misc_union_find.h \
+SeqAn-1.4.2/seqan/misc/priority_type_base.h \
+SeqAn-1.4.2/seqan/misc/priority_type_heap.h \
+SeqAn-1.4.2/seqan/modifier.h \
+SeqAn-1.4.2/seqan/modifier/INFO \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet_expansion.h \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet.h \
+SeqAn-1.4.2/seqan/modifier/modifier_functors.h \
+SeqAn-1.4.2/seqan/modifier/modifier_iterator.h \
+SeqAn-1.4.2/seqan/modifier/modifier_reverse.h \
+SeqAn-1.4.2/seqan/modifier/modifier_shortcuts.h \
+SeqAn-1.4.2/seqan/modifier/modifier_string.h \
+SeqAn-1.4.2/seqan/modifier/modifier_view.h \
+SeqAn-1.4.2/seqan/parallel.h \
+SeqAn-1.4.2/seqan/parallel/INFO \
+SeqAn-1.4.2/seqan/parallel/parallel_algorithms.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_misc.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_primitives.h \
+SeqAn-1.4.2/seqan/parallel/parallel_macros.h \
+SeqAn-1.4.2/seqan/parallel/parallel_splitting.h \
+SeqAn-1.4.2/seqan/parallel/parallel_tags.h \
+SeqAn-1.4.2/seqan/pipe.h \
+SeqAn-1.4.2/seqan/pipe/INFO \
+SeqAn-1.4.2/seqan/pipe/pipe_base.h \
+SeqAn-1.4.2/seqan/pipe/pipe_caster.h \
+SeqAn-1.4.2/seqan/pipe/pipe_counter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_echoer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_edit_environment.h \
+SeqAn-1.4.2/seqan/pipe/pipe_filter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_iterator.h \
+SeqAn-1.4.2/seqan/pipe/pipe_joiner.h \
+SeqAn-1.4.2/seqan/pipe/pipe_namer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_sampler.h \
+SeqAn-1.4.2/seqan/pipe/pipe_shifter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_source.h \
+SeqAn-1.4.2/seqan/pipe/pipe_tupler.h \
+SeqAn-1.4.2/seqan/pipe/pool_base.h \
+SeqAn-1.4.2/seqan/pipe/pool_mapper.h \
+SeqAn-1.4.2/seqan/pipe/pool_sorter.h \
+SeqAn-1.4.2/seqan/platform.h \
+SeqAn-1.4.2/seqan/platform/INFO \
+SeqAn-1.4.2/seqan/platform/platform_gcc.h \
+SeqAn-1.4.2/seqan/platform/platform_icc.h \
+SeqAn-1.4.2/seqan/platform/platform_mingw.h \
+SeqAn-1.4.2/seqan/platform/platform_nvcc.h \
+SeqAn-1.4.2/seqan/platform/platform_pgi.h \
+SeqAn-1.4.2/seqan/platform/platform_solaris.h \
+SeqAn-1.4.2/seqan/platform/platform_windows.h \
+SeqAn-1.4.2/seqan/platform/windows_stdint.h \
+SeqAn-1.4.2/seqan/random/ext_MersenneTwister.h \
+SeqAn-1.4.2/seqan/random.h \
+SeqAn-1.4.2/seqan/random/INFO \
+SeqAn-1.4.2/seqan/random/random_base.h \
+SeqAn-1.4.2/seqan/random/random_beta.h \
+SeqAn-1.4.2/seqan/random/random_beta_kfunc.h \
+SeqAn-1.4.2/seqan/random/random_geometric.h \
+SeqAn-1.4.2/seqan/random/random_lognormal.h \
+SeqAn-1.4.2/seqan/random/random_mt19937.h \
+SeqAn-1.4.2/seqan/random/random_normal.h \
+SeqAn-1.4.2/seqan/random/random_rng_functor.h \
+SeqAn-1.4.2/seqan/random/random_shuffle.h \
+SeqAn-1.4.2/seqan/random/random_uniform.h \
+SeqAn-1.4.2/seqan/score.h \
+SeqAn-1.4.2/seqan/score/INFO \
+SeqAn-1.4.2/seqan/score/score_base.h \
+SeqAn-1.4.2/seqan/score/score_edit.h \
+SeqAn-1.4.2/seqan/score/score_matrix_data.h \
+SeqAn-1.4.2/seqan/score/score_matrix.h \
+SeqAn-1.4.2/seqan/score/score_matrix_io.h \
+SeqAn-1.4.2/seqan/score/score_simple.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_impl.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_profile.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_scout.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_traceback.h \
+SeqAn-1.4.2/seqan/seeds/basic_iter_indirect.h \
+SeqAn-1.4.2/seqan/seeds.h \
+SeqAn-1.4.2/seqan/seeds/INFO \
+SeqAn-1.4.2/seqan/seeds/seeds_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_combination.h \
+SeqAn-1.4.2/seqan/seeds/seeds_extension.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_gusfield.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_chained.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_diagonal.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_non_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_unordered.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_simple.h \
+SeqAn-1.4.2/seqan/seq_io/fai_index.h \
+SeqAn-1.4.2/seqan/seq_io/genomic_region.h \
+SeqAn-1.4.2/seqan/seq_io/guess_stream_format.h \
+SeqAn-1.4.2/seqan/seq_io.h \
+SeqAn-1.4.2/seqan/seq_io/INFO \
+SeqAn-1.4.2/seqan/seq_io/read_embl.h \
+SeqAn-1.4.2/seqan/seq_io/read_fasta_fastq.h \
+SeqAn-1.4.2/seqan/seq_io/read_genbank.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream_impl.h \
+SeqAn-1.4.2/seqan/seq_io/simple_read_fasta.h \
+SeqAn-1.4.2/seqan/seq_io/write_fasta_fastq.h \
+SeqAn-1.4.2/seqan/sequence/adapt_array_pointer.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_list.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_string.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_vector.h \
+SeqAn-1.4.2/seqan/sequence.h \
+SeqAn-1.4.2/seqan/sequence/INFO \
+SeqAn-1.4.2/seqan/sequence/iter_concat_virtual.h \
+SeqAn-1.4.2/seqan/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/INFO \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_sorted_array.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entry.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled_iterator.h \
+SeqAn-1.4.2/seqan/sequence/segment_base.h \
+SeqAn-1.4.2/seqan/sequence/segment_infix.h \
+SeqAn-1.4.2/seqan/sequence/segment_prefix.h \
+SeqAn-1.4.2/seqan/sequence/segment_suffix.h \
+SeqAn-1.4.2/seqan/sequence/segment_utils.h \
+SeqAn-1.4.2/seqan/sequence/sequence_concatenator.h \
+SeqAn-1.4.2/seqan/sequence/sequence_forwards.h \
+SeqAn-1.4.2/seqan/sequence/sequence_interface.h \
+SeqAn-1.4.2/seqan/sequence/sequence_lexical.h \
+SeqAn-1.4.2/seqan/sequence/sequence_shortcuts.h \
+SeqAn-1.4.2/seqan/sequence/string_alloc.h \
+SeqAn-1.4.2/seqan/sequence/string_array.h \
+SeqAn-1.4.2/seqan/sequence/string_base.h \
+SeqAn-1.4.2/seqan/sequence/string_block.h \
+SeqAn-1.4.2/seqan/sequence/string_cstyle.h \
+SeqAn-1.4.2/seqan/sequence/string_packed.h \
+SeqAn-1.4.2/seqan/sequence/string_packed_old.h \
+SeqAn-1.4.2/seqan/sequence/string_set_base.h \
+SeqAn-1.4.2/seqan/sequence/string_set_concat_direct.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_generous.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_tight.h \
+SeqAn-1.4.2/seqan/sequence/string_set_owner.h \
+SeqAn-1.4.2/seqan/store.h \
+SeqAn-1.4.2/seqan/store/INFO \
+SeqAn-1.4.2/seqan/store/store_align.h \
+SeqAn-1.4.2/seqan/store/store_align_intervals.h \
+SeqAn-1.4.2/seqan/store/store_all.h \
+SeqAn-1.4.2/seqan/store/store_annotation.h \
+SeqAn-1.4.2/seqan/store/store_base.h \
+SeqAn-1.4.2/seqan/store/store_contig.h \
+SeqAn-1.4.2/seqan/store/store_intervaltree.h \
+SeqAn-1.4.2/seqan/store/store_io_gff.h \
+SeqAn-1.4.2/seqan/store/store_io.h \
+SeqAn-1.4.2/seqan/store/store_io_sam.h \
+SeqAn-1.4.2/seqan/store/store_io_ucsc.h \
+SeqAn-1.4.2/seqan/store/store_library.h \
+SeqAn-1.4.2/seqan/store/store_matepair.h \
+SeqAn-1.4.2/seqan/store/store_read.h \
+SeqAn-1.4.2/seqan/stream/adapt_cstdio.h \
+SeqAn-1.4.2/seqan/stream/adapt_fstream.h \
+SeqAn-1.4.2/seqan/stream/adapt_iostream.h \
+SeqAn-1.4.2/seqan/stream/adapt_mmap.h \
+SeqAn-1.4.2/seqan/stream/adapt_sstream.h \
+SeqAn-1.4.2/seqan/stream/concept_stream.h \
+SeqAn-1.4.2/seqan/stream/file_stream.h \
+SeqAn-1.4.2/seqan/stream.h \
+SeqAn-1.4.2/seqan/stream/INFO \
+SeqAn-1.4.2/seqan/stream/is.h \
+SeqAn-1.4.2/seqan/stream/lexical_cast.h \
+SeqAn-1.4.2/seqan/stream/read_auto_format.h \
+SeqAn-1.4.2/seqan/stream/read.h \
+SeqAn-1.4.2/seqan/stream/read_sam.h \
+SeqAn-1.4.2/seqan/stream/record_reader_base.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double_mmap.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single_mmap.h \
+SeqAn-1.4.2/seqan/stream/stream_base.h \
+SeqAn-1.4.2/seqan/stream/stream_bgzf.h \
+SeqAn-1.4.2/seqan/stream/stream_bz2_file.h \
+SeqAn-1.4.2/seqan/stream/stream_char_array.h \
+SeqAn-1.4.2/seqan/stream/stream_gz_file.h \
+SeqAn-1.4.2/seqan/stream/stream_put.h \
+SeqAn-1.4.2/seqan/stream/tokenize.h \
+SeqAn-1.4.2/seqan/stream/write.h \
+SeqAn-1.4.2/seqan/system/file_async.h \
+SeqAn-1.4.2/seqan/system/file_directory.h \
+SeqAn-1.4.2/seqan/system/file_forwards.h \
+SeqAn-1.4.2/seqan/system/file_sync.h \
+SeqAn-1.4.2/seqan/system.h \
+SeqAn-1.4.2/seqan/system/INFO \
+SeqAn-1.4.2/seqan/system/system_base.h \
+SeqAn-1.4.2/seqan/system/system_event.h \
+SeqAn-1.4.2/seqan/system/system_forwards.h \
+SeqAn-1.4.2/seqan/system/system_mutex.h \
+SeqAn-1.4.2/seqan/system/system_sema.h \
+SeqAn-1.4.2/seqan/system/system_thread.h \
+SeqAn-1.4.2/seqan/version.h
SAMDIR = ./samtools-0.1.18
SAMLIB = libbam.a
SAMPROG = samtools_0.1.18
-
-# $(SAMPROG)
bin_SCRIPTS = \
tophat2 \
tophat
@@ -974,9 +1055,6 @@ dist_bin_SCRIPTS = \
sra_to_solid \
tophat-fusion-post
-
-#samtools_0_1_18_SOURCES =
-#samtools_0_1_18_LDADD =
CLEANFILES = \
tophat2 \
tophat
@@ -1511,7 +1589,8 @@ info: info-am
info-am:
install-data-am:
-
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-am
install-dvi-am:
@@ -1559,38 +1638,42 @@ ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_binSCRIPTS
-.MAKE: install-am install-strip
+.MAKE: install-am install-data-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-local clean-noinstLIBRARIES cscopelist \
ctags distclean distclean-compile distclean-generic \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-binPROGRAMS install-binSCRIPTS \
- install-data install-data-am install-dist_binSCRIPTS \
- install-dvi install-dvi-am install-exec install-exec-am \
- install-html install-html-am install-info install-info-am \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
- ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \
- uninstall-binSCRIPTS uninstall-dist_binSCRIPTS
+ install-data install-data-am install-data-hook \
+ install-dist_binSCRIPTS install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-dist_binSCRIPTS
clean-local:
cd $(SAMDIR) && make clean
-tophat2: tophat2.in
- sed -e 's|__PREFIX__|$(prefix)|' tophat2.in > tophat2
+tophat2: tophat2.sh
+ cp tophat2.sh tophat2 && chmod 755 tophat2
tophat: tophat.py
- sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat
+ sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat && chmod 755 tophat
$(SAMPROG): $(SAMLIB)
$(SAMLIB):
cd $(SAMDIR) && make $(SAMPROG) && cp $(SAMLIB) $(SAMPROG) ..
+install-data-hook:
+ cp -r intervaltree sortedcontainers $(DESTDIR)$(bindir)
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/bam2fastx.cpp b/src/bam2fastx.cpp
index e500fa8..b489939 100644
--- a/src/bam2fastx.cpp
+++ b/src/bam2fastx.cpp
@@ -1,3 +1,11 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#define PACKAGE_VERSION "local"
+#define SVN_REVISION "unknown"
+#endif
+
+
#include <cstdlib>
#include <cstdio>
#include <cstring>
@@ -22,18 +30,45 @@ bool ignoreOQ=false; // ignore OQ tag
string outfname;
-#define USAGE "Usage: bam2fastx [--fasta|-a|--fastq|-q] [--color] [-Q] [--sam|-s|-t]\n\
- [-M|--mapped-only|-A|--all] [-o <outfile>] [-P|--paired] [-N] <in.bam>\n\
- \nNote: By default, reads flagged as not passing quality controls are\n\
- discarded; the -Q option can be used to ignore the QC flag.\n\
- \nUse the -N option if the /1 and /2 suffixes should be appended to\n\
- read names according to the SAM flags\n\
- \nUse the -O option to ignore the OQ tag, if present, when writing quality values\n"
+#define USAGE "bam2fastx v%s (%s) usage:\n\
+ bam2fastx [--fasta|-a] [-C|--color] [-P|--paired] [-N]\n\
+ [-A|--all|-M|--mapped-only] [-Q] [--sam|-s|-t] [-o <outfname>] <in.bam>\n\
+ \nBy default, bam2fastx only converts the unmapped reads from the input file,\n\
+ discarding those unmapped reads flagged as QC failed.\n\
+ The input BAM/SAM file MUST be sorted by read name (-n option for samtools\n\
+ sort). If the input file name is \"-\", stdin will be used instead.\n\
+ \nOptions:\n\
+ -A,--all convert all reads (mapped and unmapped)\n\
+ (but discarding those flagged as QC failed, unless -Q)\n\
+ -P paired reads are expected and converted into two output\n\
+ files (see <outfname> comments below)\n\
+ -Q convert unmapped reads even when flagged as QC failed\n\
+ -M,--maped-only convert only mapped reads\n\
+ -N for -P, append /1 and /2 suffixes to read names\n\
+ -O ignore the original quality values (OQ tag) and write the\n\
+ current quality values (default is to use OQ data if found)\n\
+ -C,--color reads are in ABI SOLiD color format\n\
+ -s,-t,--sam input is a SAM text file (default: BAM input expected)\n\
+ -a,--fasta output FASTA records, not FASTQ (discard quality values)\n\
+ -o <outfname> output file name or template (see below)\n\
+\n\
+ <outfname> serves as a name template when -P option is provided, as suffixes\n\
+ .1 and .2 will be automatically inserted before the file extension in \n\
+ <outfname>, such that two file names will be created.\n\
+ If <outfname> ends in .gz or .bz2 then bam2fastx will write the\n\
+ output compressed by gzip or bzip2 respectively.\n\n\
+ Example of converting all paired reads from a BAM file to FASTQ format:\n\
+ bam2fastx -PANQ -o sample.fq.gz sample.sortedbyname.bam\n\
+ In this example the output will be written in two files: \n\
+ sample.1.fq.gz and sample.2.fq.gz\n\
+"
-const char *short_options = "o:ac:qstOQMAPN";
+const char *short_options = "o:ac:qvhstOQCMAPN";
enum {
- OPT_FASTA = 127,
+ OPT_HELP = 127,
+ OPT_VERSION,
+ OPT_FASTA,
OPT_FASTQ,
OPT_SAM,
OPT_PAIRED,
@@ -41,7 +76,7 @@ enum {
OPT_ALL,
OPT_COLOR
};
-
+
struct Read {
string name;
int mate;
@@ -56,6 +91,8 @@ struct Read {
};
struct option long_options[] = {
+ {"help", no_argument, 0, OPT_HELP},
+ {"version", no_argument, 0, OPT_VERSION},
{"fasta", no_argument, 0, OPT_FASTA},
{"fastq", no_argument, 0, OPT_FASTQ},
{"sam", no_argument, 0, OPT_SAM},
@@ -73,54 +110,63 @@ int parse_options(int argc, char** argv)
do {
next_option = getopt_long(argc, argv, short_options, long_options, &option_index);
switch (next_option) {
- case -1:
- break;
- case 'a':
- case OPT_FASTA:
- is_fastq = false;
- break;
- case 'q':
- case OPT_FASTQ:
- is_fastq = true;
- break;
- case 's':
- case 't':
- case OPT_SAM: //sam (text) input
- sam_input = true;
- break;
- case 'M':
- case OPT_MAPPED_ONLY:
- mapped_only = true;
+ case -1:
break;
- case 'A':
- case OPT_ALL:
- all_reads = true;
- break;
- case OPT_COLOR:
- color = true;
- break;
- case 'P':
- case OPT_PAIRED:
- pairs = true;
- break;
- case 'Q':
- ignoreQC = true;
- break;
- case 'O':
- ignoreOQ = true;
- break;
- case 'o':
- outfname=optarg;
- break;
- case 'N':
- add_matenum=true;
- break;
- default:
- return 1;
- }
+ case 'h':
+ case OPT_HELP:
+ fprintf(stdout, USAGE, PACKAGE_VERSION, SVN_REVISION);
+ exit(0);
+ case 'v':
+ case OPT_VERSION:
+ fprintf(stdout, "%s\n", PACKAGE_VERSION);
+ exit(0);
+ case 'a':
+ case OPT_FASTA:
+ is_fastq = false;
+ break;
+ case 'q':
+ case OPT_FASTQ:
+ is_fastq = true;
+ break;
+ case 's':
+ case 't':
+ case OPT_SAM: //sam (text) input
+ sam_input = true;
+ break;
+ case 'M':
+ case OPT_MAPPED_ONLY:
+ mapped_only = true;
+ break;
+ case 'A':
+ case OPT_ALL:
+ all_reads = true;
+ break;
+ case 'C':
+ case OPT_COLOR:
+ color = true;
+ break;
+ case 'P':
+ case OPT_PAIRED:
+ pairs = true;
+ break;
+ case 'Q':
+ ignoreQC = true;
+ break;
+ case 'O':
+ ignoreOQ = true;
+ break;
+ case 'o':
+ outfname=optarg;
+ break;
+ case 'N':
+ add_matenum=true;
+ break;
+ default:
+ return 1;
+ }
} while(next_option != -1);
if (all_reads && mapped_only) {
- fprintf(stderr, "Error: incompatible options !\n");
+ fprintf(stderr, "Error: incompatible options, use either -A/--all or -M/--mapped-only!\n");
exit(2);
}
return 0;
@@ -322,13 +368,13 @@ int main(int argc, char *argv[])
char* fname=NULL;
bool use_pclose=false;
if (parse_options(argc, argv) || optind>=argc) {
- fprintf(stderr, USAGE);
+ fprintf(stderr, USAGE, PACKAGE_VERSION, SVN_REVISION);
return -1;
}
fname=argv[optind++];
if (fname==NULL || fname[0]==0) {
- fprintf(stderr, USAGE);
+ fprintf(stderr, USAGE, PACKAGE_VERSION, SVN_REVISION);
return 1;
}
if (sam_input)
diff --git a/src/bam_merge.h b/src/bam_merge.h
index 6241e31..d7db357 100644
--- a/src/bam_merge.h
+++ b/src/bam_merge.h
@@ -43,6 +43,9 @@ struct equal_bam {
if (first.b->core.n_cigar != second.b->core.n_cigar)
return false;
+
+ if ((first.b->core.flag & BAM_FREVERSE) != (second.b->core.flag & BAM_FREVERSE))
+ return false;
for (int i = 0; i < first.b->core.n_cigar; ++i){
if (bam1_cigar(first.b)[i] != bam1_cigar(second.b)[i])
diff --git a/src/common.cpp b/src/common.cpp
index 750e8cb..4a12292 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -969,7 +969,7 @@ uint8_t* dupalloc_bdata(bam1_t *b, int size) {
return odata; //user must FREE this after
}
-extern unsigned short bam_char2flag_table[];
+//extern unsigned short bam_char2flag_table[];
GBamRecord::GBamRecord(const char* qname, int32_t gseq_tid,
int pos, bool reverse, const char* qseq, const char* cigar, const char* quals) {
@@ -984,7 +984,7 @@ GBamRecord::GBamRecord(const char* qname, int32_t gseq_tid,
b->core.tid=gseq_tid;
b->core.mtid=-1;
b->core.mpos=-1;
- b->core.qual=255;
+ b->core.qual=0;
int l_qseq=strlen(qseq);
//this may not be accurate, setting CIGAR is the correct way
//b->core.bin = bam_reg2bin(b->core.pos, b->core.pos+l_qseq-1);
diff --git a/src/common.h b/src/common.h
index 6f92ec0..6bea311 100644
--- a/src/common.h
+++ b/src/common.h
@@ -576,13 +576,13 @@ class GBamWriter {
}
void write(bam1_t* b, int64_t read_id=0) {
int64_t pre_block_addr=0; //offsets after last write()
- int pre_block_offs=0; //but before this write()
+ //int pre_block_offs=0; //but before this write()
int64_t pre_pos=0;
bool write_index=false;
if (findex && read_id) {
if (idxcount >= INDEX_REC_COUNT && read_id != idx_last_id) {
pre_pos = this->tell();
- pre_block_offs = pre_pos & 0xFFFF;
+ //pre_block_offs = pre_pos & 0xFFFF;
pre_block_addr = (pre_pos >> 16) & 0xFFFFFFFFFFFFLL;
write_index=true;
}
diff --git a/src/gff.cpp b/src/gff.cpp
index d485aae..cc954cd 100644
--- a/src/gff.cpp
+++ b/src/gff.cpp
@@ -55,7 +55,8 @@ int gfo_cmpByLoc(const pointer p1, const pointer p2) {
return (int)(g1.end-g2.end);
else return strcmp(g1.getID(), g2.getID());
}
- else return (int)(g1.gseq_id-g2.gseq_id);
+ else //return (int)(g1.gseq_id-g2.gseq_id); // input order !
+ return strcmp(g1.getGSeqName(), g2.getGSeqName()); //lexicographic !
}
char* GffLine::extractAttr(const char* attr, bool caseStrict, bool enforce_GTF2) {
@@ -695,6 +696,7 @@ chr1 hg18_knownGene exon 69805456 69806912 0.000000 + .
// -- make sure any other related boundaries are updated:
start=exons.First()->start;
end=exons.Last()->end;
+ /*
if (uptr!=NULL) { //collect stats about the underlying genomic sequence
GSeqStat* gsd=(GSeqStat*)uptr;
if (start<gsd->mincoord) gsd->mincoord=start;
@@ -704,6 +706,7 @@ chr1 hg18_knownGene exon 69805456 69806912 0.000000 + .
gsd->maxfeat=this;
}
}
+ */
}
void GffObj::removeExon(int idx) {
@@ -770,7 +773,9 @@ GffObj::GffObj(GffReader *gfrd, GffLine* gffline, bool keepAttr, bool noExonAttr
if (gfrd==NULL)
GError("Cannot use this GffObj constructor with a NULL GffReader!\n");
gffnames_ref(names);
- if (gfrd->names==NULL) gfrd->names=names;
+ if (gfrd->names==NULL) {
+ gfrd->names=names;
+ }
//qlen=0;qstart=0;qend=0;
gscore=0;
uscore=0;
@@ -849,17 +854,9 @@ GffObj::GffObj(GffReader *gfrd, GffLine* gffline, bool keepAttr, bool noExonAttr
geneID=Gstrdup(gffline->parents[0]);
}
- //GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,names->gseqs.lastNameUsed()),true);
- GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,gffline->gseqname), true);
- uptr=gsd;
- /*
- if (start<gsd->mincoord) gsd->mincoord=start;
- if (end>gsd->maxcoord) gsd->maxcoord=end;
- if (this->len()>gsd->maxfeat_len) {
- gsd->maxfeat_len=this->len();
- gsd->maxfeat=this;
- }
- */
+ //GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,gffline->gseqname), true);
+ //GSeqStat* gsd=gfrd->gseqtable[gseq_id];
+ //uptr=gsd;
}
GffLine* GffReader::nextGffLine() {
@@ -917,7 +914,6 @@ GffObj* GffReader::gfoAdd(GffObj* gfo) {
GPVec<GffObj>* glst=phash.Find(gfo->gffID);
if (glst==NULL)
glst=new GPVec<GffObj>(false);
- //GfoHolder gh(gfo); //,idx);
int i=glst->Add(gfo);
phash.Add(gfo->gffID, glst);
return glst->Get(i);
@@ -998,25 +994,12 @@ GffObj* GffReader::newGffRec(GffLine* gffline, bool keepAttr, bool noExonAttr,
GffObj* parent, GffExon* pexon, GPVec<GffObj>* glst) {
GffObj* newgfo=new GffObj(this, gffline, keepAttr, noExonAttr);
GffObj* r=NULL;
- //int gfoidx=gflst.Add(newgfo);
gflst.Add(newgfo);
r=(glst) ? gfoAdd(*glst, newgfo) : gfoAdd(newgfo);
if (parent!=NULL) {
updateParent(r, parent);
if (pexon!=NULL) parent->removeExon(pexon);
}
- /*
- if (gff_warns) {
- int* pcount=tids.Find(newgfo->gffID);
- if (pcount!=NULL) {
- if (gff_warns) GMessage("Warning: duplicate GFF ID: %s\n", newgfo->gffID);
- (*pcount)++;
- }
- else {
- tids.Add(newgfo->gffID,new int(1));
- }
- }
- */
return r;
}
@@ -1117,11 +1100,11 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
GffObj* prevseen=NULL;
GPVec<GffObj>* prevgflst=NULL;
if (gffline->ID && gffline->exontype==0) {
- //>> for a parent-like IDed feature (mRNA, gene, etc.)
- //look for same ID on the same chromosome/strand/locus
+ //parent-like feature ID (mRNA, gene, etc.)
+ //check if this ID was previously seen on the same chromosome/strand within GFF_MAX_LOCUS distance
prevseen=gfoFind(gffline->ID, prevgflst, gffline->gseqname, gffline->strand, gffline->fstart);
- if (prevseen!=NULL) {
- //same ID/chromosome combo encountered before
+ if (prevseen) {
+ //same ID seen in the same locus/region
if (prevseen->createdByExon()) {
if (gff_show_warnings && (prevseen->start<gffline->fstart ||
prevseen->end>gffline->fend))
@@ -1130,14 +1113,14 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
//this line has the main attributes for this ID
updateGffRec(prevseen, gffline, keepAttr);
}
- else {
- //- duplicate ID -- this must be a discontinuous feature according to GFF3 specs
- // e.g. a trans-spliced transcript
+ else
+ { //duplicate ID -- but this could also be a discontinuous feature according to GFF3 specs
+ //e.g. a trans-spliced transcript - but segments should not overlap
if (prevseen->overlap(gffline->fstart, gffline->fend)) {
- //overlapping with same ID not allowed
- GMessage("GFF Error: duplicate/invalid '%s' feature ID=%s\n", gffline->ftype, gffline->ID);
+ //overlapping feature with same ID is going too far
+ GMessage("GFF Error: overlapping duplicate %s feature (ID=%s)\n", gffline->ftype, gffline->ID);
//validation_errors = true;
- if (gff_warns) {
+ if (gff_warns) { //validation intent: just skip the feature, allow the user to see other errors
delete gffline;
gffline=NULL;
continue;
@@ -1145,6 +1128,7 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
else exit(1);
}
//create a new entry with the same ID
+ /*
int distance=INT_MAX;
if (prevseen->isTranscript() && prevseen->strand==gffline->strand) {
if (prevseen->start>=gffline->fstart)
@@ -1156,18 +1140,28 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
//exception: make this an exon of previous ID
//addExonFeature(prevseen, gffline, pex, noExonAttr);
prevseen->addExon(this, gffline, false, true);
+ if (gff_warns) {
+ GMessage("GFF Warning: duplicate feature ID %s (%d-%d) added as exon of previous %d-%d!\n",
+ gffline->ID, gffline->fstart, gffline->fend, prevseen->start, prevseen->end);
+ }
}
- else { //create a separate entry (true discontinuous feature)
+ else {
+ */
+ //create a separate entry (true discontinuous feature)
prevseen=newGffRec(gffline, keepAttr, noExonAttr,
prevseen->parent, NULL, prevgflst);
- }
- } //duplicate ID on the same chromosome
- } //prevseeen != NULL
- } //parent-like ID feature
+ if (gff_warns) {
+ GMessage("GFF Warning: duplicate feature ID %s (%d-%d) (discontinuous feature?)\n",
+ gffline->ID, gffline->fstart, gffline->fend);
+ }
+ //}
+ } //duplicate ID in the same locus
+ } //ID seen previously in the same locus
+ } //parent-like ID feature (non-exon)
if (gffline->parents==NULL) {//start GFF3-like record with no parent (mRNA, gene)
if (!prevseen) newGffRec(gffline, keepAttr, noExonAttr, NULL, NULL, prevgflst);
}
- else { //--- it's a child feature (exon/CDS but could still be a mRNA with gene(s) as parent)
+ else { //--- it's a child feature (exon/CDS or even a mRNA with a gene as parent)
//updates all the declared parents with this child
bool found_parent=false;
GffObj* newgfo=prevseen;
@@ -1215,7 +1209,7 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
}
}
else { //potential exon subfeature?
- //always discards dummy "intron" features
+ //always discard dummy "intron" features
if (!(gffline->exontype==exgffIntron && (parentgfo->isTranscript() || parentgfo->exons.Count()>0))) {
if (!addExonFeature(parentgfo, gffline, pex, noExonAttr))
validation_errors=true;
@@ -1257,10 +1251,6 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
}//while gff lines
if (gflst.Count()>0) {
gflst.finalize(this, mergeCloseExons, keepAttr, noExonAttr); //force sorting by locus if so constructed
- gseqStats.setCount(gseqstats.Last()->gseqid+1);
- for (int gi=0;gi<gseqstats.Count();gi++) {
- gseqStats.Put(gseqstats[gi]->gseqid, gseqstats[gi]); //copy the pointer only
- }
}
// all gff records are now loaded in GList gflst
// so we can free the hash
@@ -1273,10 +1263,6 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
void GfList::finalize(GffReader* gfr, bool mergeCloseExons,
bool keepAttrs, bool noExonAttr) { //if set, enforce sort by locus
- if (mustSort) { //force (re-)sorting
- this->setSorted(false);
- this->setSorted((GCompareProc*)gfo_cmpByLoc);
- }
GList<GffObj> discarded(false,true,false);
for (int i=0;i<Count();i++) {
//finish the parsing for each GffObj
@@ -1296,94 +1282,106 @@ void GfList::finalize(GffReader* gfr, bool mergeCloseExons,
if (discarded.Count()>0) {
this->Pack();
}
+ if (mustSort) { //force (re-)sorting
+ this->setSorted(false);
+ this->setSorted((GCompareProc*)gfo_cmpByLoc);
+ }
}
GffObj* GffObj::finalize(GffReader* gfr, bool mergeCloseExons, bool keepAttrs, bool noExonAttr) {
//merge
//always merge adjacent or overlapping segments
//but if mergeCloseExons then merge even when distance is up to 5 bases
- udata=0;
- uptr=NULL;
if (gfr->transcriptsOnly && !(isTranscript() || (isGene() && children.Count()==0))) {
- isDiscarded(true);
- }
+ isDiscarded(true);
+ }
if (ftype_id==gff_fid_transcript && CDstart>0) {
- ftype_id=gff_fid_mRNA;
- //exon_ftype_id=gff_fid_exon;
- }
+ ftype_id=gff_fid_mRNA;
+ //exon_ftype_id=gff_fid_exon;
+ }
if (exons.Count()>0 && (isTranscript() || exon_ftype_id==gff_fid_exon)) {
- if (mergeCloseExons) {
- int mindist=mergeCloseExons ? 5:1;
- for (int i=0;i<exons.Count()-1;i++) {
- int ni=i+1;
- uint mend=exons[i]->end;
- while (ni<exons.Count()) {
- int dist=(int)(exons[ni]->start-mend);
- if (dist>mindist) break; //no merging with next segment
- if (gfr!=NULL && gfr->gff_warns && dist!=0 && (exons[ni]->exontype!=exgffUTR && exons[i]->exontype!=exgffUTR)) {
- GMessage("GFF warning: merging adjacent/overlapping segments of %s on %s (%d-%d, %d-%d)\n",
- gffID, getGSeqName(), exons[i]->start, exons[i]->end,exons[ni]->start, exons[ni]->end);
- }
- mend=exons[ni]->end;
- covlen-=exons[i]->len();
- exons[i]->end=mend;
- covlen+=exons[i]->len();
- covlen-=exons[ni]->len();
- if (exons[ni]->attrs!=NULL && (exons[i]->attrs==NULL ||
- exons[i]->attrs->Count()<exons[ni]->attrs->Count())) {
- //use the other exon attributes, if more
- delete(exons[i]->attrs);
- exons[i]->attrs=exons[ni]->attrs;
- exons[ni]->attrs=NULL;
- }
- exons.Delete(ni);
- } //check for merge with next exon
- } //for each exon
- } //merge close exons
- //shrink transcript to the exons' span
- this->start=exons.First()->start;
- this->end=exons.Last()->end;
- //also update the stats for the reference sequence
- if (uptr!=NULL) { //collect stats about the underlying genomic sequence
- GSeqStat* gsd=(GSeqStat*)uptr;
- if (start<gsd->mincoord) gsd->mincoord=start;
- if (end>gsd->maxcoord) gsd->maxcoord=end;
- if (this->len()>gsd->maxfeat_len) {
- gsd->maxfeat_len=this->len();
- gsd->maxfeat=this;
- }
- }
- this->uptr=NULL;
- this->udata=0;
+ if (mergeCloseExons) {
+ int mindist=mergeCloseExons ? 5:1;
+ for (int i=0;i<exons.Count()-1;i++) {
+ int ni=i+1;
+ uint mend=exons[i]->end;
+ while (ni<exons.Count()) {
+ int dist=(int)(exons[ni]->start-mend);
+ if (dist>mindist) break; //no merging with next segment
+ if (gfr!=NULL && gfr->gff_warns && dist!=0 && (exons[ni]->exontype!=exgffUTR && exons[i]->exontype!=exgffUTR)) {
+ GMessage("GFF warning: merging adjacent/overlapping segments of %s on %s (%d-%d, %d-%d)\n",
+ gffID, getGSeqName(), exons[i]->start, exons[i]->end,exons[ni]->start, exons[ni]->end);
+ }
+ mend=exons[ni]->end;
+ covlen-=exons[i]->len();
+ exons[i]->end=mend;
+ covlen+=exons[i]->len();
+ covlen-=exons[ni]->len();
+ if (exons[ni]->attrs!=NULL && (exons[i]->attrs==NULL ||
+ exons[i]->attrs->Count()<exons[ni]->attrs->Count())) {
+ //use the other exon attributes, if more
+ delete(exons[i]->attrs);
+ exons[i]->attrs=exons[ni]->attrs;
+ exons[ni]->attrs=NULL;
+ }
+ exons.Delete(ni);
+ } //check for merge with next exon
+ } //for each exon
+ } //merge close exons
+ //shrink transcript to the exons' span
+ this->start=exons.First()->start;
+ this->end=exons.Last()->end;
+ //also update the stats for the reference sequence
+ if (!this->isDiscarded()) { //collect stats about the underlying genomic sequence
+ if (gfr->gseqtable.Count()<=gseq_id) {
+ gfr->gseqtable.setCount(gseq_id+1);
+ }
+ GSeqStat* gsd=gfr->gseqtable[gseq_id];
+ if (gsd==NULL) {
+ gsd=new GSeqStat(gseq_id,names->gseqs.getName(gseq_id));
+ gfr->gseqtable.Put(gseq_id, gsd);
+ gfr->gseqStats.Add(gsd);
+ }
+ gsd->fcount++;
+ if (start<gsd->mincoord) gsd->mincoord=start;
+ if (end>gsd->maxcoord) gsd->maxcoord=end;
+ if (this->len()>gsd->maxfeat_len) {
+ gsd->maxfeat_len=this->len();
+ gsd->maxfeat=this;
+ }
+ }
+ uptr=NULL;
+ udata=0;
}
+
//attribute reduction for GTF records
if (keepAttrs && !noExonAttr && !hasGffID()
- && exons.Count()>0 && exons[0]->attrs!=NULL) {
- bool attrs_discarded=false;
- for (int a=0;a<exons[0]->attrs->Count();a++) {
- int attr_name_id=exons[0]->attrs->Get(a)->attr_id;
- char* attr_name=names->attrs.getName(attr_name_id);
- char* attr_val =exons[0]->attrs->Get(a)->attr_val;
- bool sameExonAttr=true;
- for (int i=1;i<exons.Count();i++) {
- char* ov=exons[i]->getAttr(attr_name_id);
- if (ov==NULL || (strcmp(ov,attr_val)!=0)) {
- sameExonAttr=false;
- break;
- }
- }
- if (sameExonAttr) {
- //delete this attribute from exons level
- attrs_discarded=true;
- this->addAttr(attr_name, attr_val);
- for (int i=1;i<exons.Count();i++) {
- removeExonAttr(*(exons[i]), attr_name_id);
- }
- exons[0]->attrs->freeItem(a);
- }
- }
- if (attrs_discarded) exons[0]->attrs->Pack();
- }
+ && exons.Count()>0 && exons[0]->attrs!=NULL) {
+ bool attrs_discarded=false;
+ for (int a=0;a<exons[0]->attrs->Count();a++) {
+ int attr_name_id=exons[0]->attrs->Get(a)->attr_id;
+ char* attr_name=names->attrs.getName(attr_name_id);
+ char* attr_val =exons[0]->attrs->Get(a)->attr_val;
+ bool sameExonAttr=true;
+ for (int i=1;i<exons.Count();i++) {
+ char* ov=exons[i]->getAttr(attr_name_id);
+ if (ov==NULL || (strcmp(ov,attr_val)!=0)) {
+ sameExonAttr=false;
+ break;
+ }
+ }
+ if (sameExonAttr) {
+ //delete this attribute from exons level
+ attrs_discarded=true;
+ this->addAttr(attr_name, attr_val);
+ for (int i=1;i<exons.Count();i++) {
+ removeExonAttr(*(exons[i]), attr_name_id);
+ }
+ exons[0]->attrs->freeItem(a);
+ }
+ }
+ if (attrs_discarded) exons[0]->attrs->Pack();
+ }
return this;
}
diff --git a/src/gff.h b/src/gff.h
index edf2b69..ba0b762 100644
--- a/src/gff.h
+++ b/src/gff.h
@@ -243,7 +243,7 @@ class GffNameInfo {
}
};
-class GffNameList:public GList<GffNameInfo> {
+class GffNameList:public GPVec<GffNameInfo> {
friend class GffNameInfo;
friend class GffNames;
protected:
@@ -256,7 +256,8 @@ protected:
byName.shkAdd(f->name,f);
}
public:
- GffNameList(int init_capacity=6):GList<GffNameInfo>(init_capacity, false,true,true), byName(false) {
+ //GffNameList(int init_capacity=6):GList<GffNameInfo>(init_capacity, false,true,true), byName(false) {
+ GffNameList(int init_capacity=6):GPVec<GffNameInfo>(init_capacity, true), byName(false) {
idlast=-1;
setCapacity(init_capacity);
}
@@ -428,6 +429,7 @@ class GffCDSeg:public GSeg {
char phase;
int exonidx;
};
+
//one GFF mRNA object -- e.g. a mRNA with its exons and/or CDS segments
class GffObj:public GSeg {
//utility segment-merging function for addExon()
@@ -451,6 +453,7 @@ class GffObj:public GSeg {
friend class GffExon;
public:
static GffNames* names; // dictionary storage that holds the various attribute names etc.
+ //TODO: this makes the parser thread unsafe, use conditional compiling for names access!
int track_id; // index of track name in names->tracks
int gseq_id; // index of genomic sequence name in names->gseqs
int ftype_id; // index of this record's feature name in names->feats, or the special gff_fid_mRNA value
@@ -1010,7 +1013,7 @@ class GffReader {
bool transcriptsOnly; //keep only transcripts w/ their exon/CDS features
GHash<int> discarded_ids; //for transcriptsOnly mode, keep track
// of discarded parent IDs
- GHash< GPVec<GffObj> > phash; //transcript_id+contig (Parent~Contig) => [gflst index, GffObj]
+ GHash< GPVec<GffObj> > phash; //transcript_id => GPVec<GffObj>(false)
//GHash<int> tids; //just for transcript_id uniqueness
char* gfoBuildId(const char* id, const char* ctg);
//void gfoRemove(const char* id, const char* ctg);
@@ -1024,12 +1027,12 @@ class GffReader {
void subfPoolAdd(GHash<CNonExon>& pex, GffObj* newgfo);
GffObj* promoteFeature(CNonExon* subp, char*& subp_name, GHash<CNonExon>& pex,
bool keepAttr, bool noExonAttr);
- GList<GSeqStat> gseqstats; //list of all genomic sequences seen by this reader, accumulates stats
#ifdef CUFFLINKS
boost::crc_32_type _crc_result;
#endif
public:
- GffNames* names; //just a pointer to the global static Gff names repository in GffObj
+ GPVec<GSeqStat> gseqtable; //table with all genomic sequences, but only current GXF gseq ID indices will have non-NULL
+ GffNames* names; //just a pointer to the global static Gff names repository
GfList gflst; //accumulate GffObjs being read
GffObj* newGffRec(GffLine* gffline, bool keepAttr, bool noExonAttr,
GffObj* parent=NULL, GffExon* pexon=NULL, GPVec<GffObj>* glst=NULL);
@@ -1038,9 +1041,9 @@ class GffReader {
bool keepAttr);
GffObj* updateParent(GffObj* newgfh, GffObj* parent);
bool addExonFeature(GffObj* prevgfo, GffLine* gffline, GHash<CNonExon>& pex, bool noExonAttr);
- GPVec<GSeqStat> gseqStats; //only populated after finalize()
+ GPVec<GSeqStat> gseqStats; //populated after finalize() with only the ref seqs in this file
GffReader(FILE* f=NULL, bool t_only=false, bool sortbyloc=false):discarded_ids(true),
- phash(true), gseqstats(true,true,true), gflst(sortbyloc), gseqStats(1, false) {
+ phash(true), gseqtable(1,true), gflst(sortbyloc), gseqStats(1, false) {
gff_warns=gff_show_warnings;
names=NULL;
gffline=NULL;
@@ -1059,8 +1062,8 @@ class GffReader {
transcriptsOnly=t_only;
gflst.sortedByLoc(sortbyloc);
}
- GffReader(char* fn, bool t_only=false, bool sort=false):discarded_ids(true), phash(true),
- gseqstats(true,true,true), gflst(sort), gseqStats(1,false) {
+ GffReader(const char* fn, bool t_only=false, bool sort=false):discarded_ids(true), phash(true),
+ gseqtable(1,true), gflst(sort), gseqStats(1,false) {
gff_warns=gff_show_warnings;
names=NULL;
fname=Gstrdup(fn);
@@ -1076,11 +1079,11 @@ class GffReader {
delete gffline;
gffline=NULL;
fpos=0;
+ if (fh) fclose(fh);
gflst.freeUnused();
gflst.Clear();
discarded_ids.Clear();
phash.Clear();
- gseqstats.Clear();
GFREE(fname);
GFREE(linebuf);
}
diff --git a/src/intervaltree/__init__.py b/src/intervaltree/__init__.py
new file mode 100755
index 0000000..4b8690f
--- /dev/null
+++ b/src/intervaltree/__init__.py
@@ -0,0 +1,22 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Root package.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from .interval import Interval
+from .intervaltree import IntervalTree
diff --git a/src/intervaltree/interval.py b/src/intervaltree/interval.py
new file mode 100755
index 0000000..4c19cba
--- /dev/null
+++ b/src/intervaltree/interval.py
@@ -0,0 +1,302 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Interval class
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from numbers import Number
+from collections import namedtuple
+
+
+# noinspection PyBroadException
+class Interval(namedtuple('IntervalBase', ['begin', 'end', 'data'])):
+ __slots__ = () # Saves memory, avoiding the need to create __dict__ for each interval
+
+ def __new__(cls, begin, end, data=None):
+ return super(Interval, cls).__new__(cls, begin, end, data)
+
+ def overlaps(self, begin, end=None):
+ """
+ Whether the interval overlaps the given point, range or Interval.
+ :param begin: beginning point of the range, or the point, or an Interval
+ :param end: end point of the range. Optional if not testing ranges.
+ :return: True or False
+ :rtype: bool
+ """
+ if end is not None:
+ return (
+ (begin <= self.begin < end) or
+ (begin < self.end <= end) or
+ (self.begin <= begin < self.end) or
+ (self.begin < end <= self.end)
+ )
+ try:
+ return self.overlaps(begin.begin, begin.end)
+ except:
+ return self.contains_point(begin)
+
+ def contains_point(self, p):
+ """
+ Whether the Interval contains p.
+ :param p: a point
+ :return: True or False
+ :rtype: bool
+ """
+ return self.begin <= p < self.end
+
+ def range_matches(self, other):
+ """
+ Whether the begins equal and the ends equal. Compare __eq__().
+ :param other: Interval
+ :return: True or False
+ :rtype: bool
+ """
+ return (
+ self.begin == other.begin and
+ self.end == other.end
+ )
+
+ def contains_interval(self, other):
+ """
+ Whether other is contained in this Interval.
+ :param other: Interval
+ :return: True or False
+ :rtype: bool
+ """
+ return (
+ self.begin <= other.begin and
+ self.end >= other.end
+ )
+
+ def distance_to(self, other):
+ """
+ Returns the size of the gap between intervals, or 0
+ if they touch or overlap.
+ :param other: Interval or point
+ :return: distance
+ :rtype: Number
+ """
+ if self.overlaps(other):
+ return 0
+ try:
+ if self.begin < other.begin:
+ return other.begin - self.end
+ else:
+ return self.begin - other.end
+ except:
+ if self.end < other:
+ return other - self.end
+ else:
+ return self.begin - other
+
+ def is_null(self):
+ """
+ Whether this equals the null interval.
+ :return: True if end <= begin else False
+ :rtype: bool
+ """
+ return self.begin >= self.end
+
+ def length(self):
+ """
+ The distance covered by this Interval.
+ :return: length
+ :type: Number
+ """
+ if self.is_null():
+ return 0
+ return self.end - self.begin
+
+ def __hash__(self):
+ """
+ Depends on begin and end only.
+ :return: hash
+ :rtype: Number
+ """
+ return hash((self.begin, self.end))
+
+ def __eq__(self, other):
+ """
+ Whether the begins equal, the ends equal, and the data fields
+ equal. Compare range_matches().
+ :param other: Interval
+ :return: True or False
+ :rtype: bool
+ """
+ return (
+ self.begin == other.begin and
+ self.end == other.end and
+ self.data == other.data
+ )
+
+ def __cmp__(self, other):
+ """
+ Tells whether other sorts before, after or equal to this
+ Interval.
+
+ Sorting is by begins, then by ends, then by data fields.
+
+ If data fields are not both sortable types, data fields are
+ compared alphabetically by type name.
+ :param other: Interval
+ :return: -1, 0, 1
+ :rtype: int
+ """
+ s = self[0:2]
+ try:
+ o = other[0:2]
+ except:
+ o = (other,)
+ if s != o:
+ return -1 if s < o else 1
+ try:
+ if self.data == other.data:
+ return 0
+ return -1 if self.data < other.data else 1
+ except TypeError:
+ s = type(self.data).__name__
+ o = type(other.data).__name__
+ if s == o:
+ return 0
+ return -1 if s < o else 1
+
+ def __lt__(self, other):
+ """
+ Less than operator. Parrots __cmp__()
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ return self.__cmp__(other) < 0
+
+ def __gt__(self, other):
+ """
+ Greater than operator. Parrots __cmp__()
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ return self.__cmp__(other) > 0
+
+ def _raise_if_null(self, other):
+ """
+ :raises ValueError: if either self or other is a null Interval
+ """
+ if self.is_null():
+ raise ValueError("Cannot compare null Intervals!")
+ if hasattr(other, 'is_null') and other.is_null():
+ raise ValueError("Cannot compare null Intervals!")
+
+ def lt(self, other):
+ """
+ Strictly less than. Returns True if no part of this Interval
+ extends higher than or into other.
+ :raises ValueError: if either self or other is a null Interval
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ self._raise_if_null(other)
+ return self.end <= getattr(other, 'begin', other)
+
+ def le(self, other):
+ """
+ Less than or overlaps. Returns True if no part of this Interval
+ extends higher than other.
+ :raises ValueError: if either self or other is a null Interval
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ self._raise_if_null(other)
+ return self.end <= getattr(other, 'end', other)
+
+ def gt(self, other):
+ """
+ Strictly greater than. Returns True if no part of this Interval
+ extends lower than or into other.
+ :raises ValueError: if either self or other is a null Interval
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ self._raise_if_null(other)
+ if hasattr(other, 'end'):
+ return self.begin >= other.end
+ else:
+ return self.begin > other
+
+ def ge(self, other):
+ """
+ Greater than or overlaps. Returns True if no part of this Interval
+ extends lower than other.
+ :raises ValueError: if either self or other is a null Interval
+ :param other: Interval or point
+ :return: True or False
+ :rtype: bool
+ """
+ self._raise_if_null(other)
+ return self.begin >= getattr(other, 'begin', other)
+
+ def _get_fields(self):
+ """
+ Used by str, unicode, repr and __reduce__.
+
+ Returns only the fields necessary to reconstruct the Interval.
+ :return: reconstruction info
+ :rtype: tuple
+ """
+ if self.data is not None:
+ return self.begin, self.end, self.data
+ else:
+ return self.begin, self.end
+
+ def __repr__(self):
+ """
+ Executable string representation of this Interval.
+ :return: string representation
+ :rtype: str
+ """
+ if isinstance(self.begin, Number):
+ s_begin = str(self.begin)
+ s_end = str(self.end)
+ else:
+ s_begin = repr(self.begin)
+ s_end = repr(self.end)
+ if self.data is None:
+ return "Interval({0}, {1})".format(s_begin, s_end)
+ else:
+ return "Interval({0}, {1}, {2})".format(s_begin, s_end, repr(self.data))
+
+ __str__ = __repr__
+
+ def copy(self):
+ """
+ Shallow copy.
+ :return: copy of self
+ :rtype: Interval
+ """
+ return Interval(self.begin, self.end, self.data)
+
+ def __reduce__(self):
+ """
+ For pickle-ing.
+ :return: pickle data
+ :rtype: tuple
+ """
+ return Interval, self._get_fields()
diff --git a/src/intervaltree/intervaltree.py b/src/intervaltree/intervaltree.py
new file mode 100755
index 0000000..0366f5f
--- /dev/null
+++ b/src/intervaltree/intervaltree.py
@@ -0,0 +1,947 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Core logic.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications Copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from .interval import Interval
+from .node import Node
+from numbers import Number
+import collections
+from sortedcontainers import SortedDict
+from warnings import warn
+
+try:
+ xrange # Python 2?
+except NameError:
+ xrange = range
+
+
+# noinspection PyBroadException
+class IntervalTree(collections.MutableSet):
+ """
+ A binary lookup tree of intervals.
+ The intervals contained in the tree are represented using ``Interval(a, b, data)`` objects.
+ Each such object represents a half-open interval ``[a, b)`` with optional data.
+
+ Examples:
+ ---------
+
+ Initialize a blank tree::
+
+ >>> tree = IntervalTree()
+ >>> tree
+ IntervalTree()
+
+ Initialize a tree from an iterable set of Intervals in O(n * log n)::
+
+ >>> tree = IntervalTree([Interval(-10, 10), Interval(-20.0, -10.0)])
+ >>> tree
+ IntervalTree([Interval(-20.0, -10.0), Interval(-10, 10)])
+ >>> len(tree)
+ 2
+
+ Note that this is a set, i.e. repeated intervals are ignored. However,
+ Intervals with different data fields are regarded as different::
+
+ >>> tree = IntervalTree([Interval(-10, 10), Interval(-10, 10), Interval(-10, 10, "x")])
+ >>> tree
+ IntervalTree([Interval(-10, 10), Interval(-10, 10, 'x')])
+ >>> len(tree)
+ 2
+
+ Insertions::
+ >>> tree = IntervalTree()
+ >>> tree[0:1] = "data"
+ >>> tree.add(Interval(10, 20))
+ >>> tree.addi(19.9, 20)
+ >>> tree
+ IntervalTree([Interval(0, 1, 'data'), Interval(10, 20), Interval(19.9, 20)])
+ >>> tree.update([Interval(19.9, 20.1), Interval(20.1, 30)])
+ >>> len(tree)
+ 5
+
+ Inserting the same Interval twice does nothing::
+ >>> tree = IntervalTree()
+ >>> tree[-10:20] = "arbitrary data"
+ >>> tree[-10:20] = None # Note that this is also an insertion
+ >>> tree
+ IntervalTree([Interval(-10, 20), Interval(-10, 20, 'arbitrary data')])
+ >>> tree[-10:20] = None # This won't change anything
+ >>> tree[-10:20] = "arbitrary data" # Neither will this
+ >>> len(tree)
+ 2
+
+ Deletions::
+ >>> tree = IntervalTree(Interval(b, e) for b, e in [(-10, 10), (-20, -10), (10, 20)])
+ >>> tree
+ IntervalTree([Interval(-20, -10), Interval(-10, 10), Interval(10, 20)])
+ >>> tree.remove(Interval(-10, 10))
+ >>> tree
+ IntervalTree([Interval(-20, -10), Interval(10, 20)])
+ >>> tree.remove(Interval(-10, 10))
+ Traceback (most recent call last):
+ ...
+ ValueError
+ >>> tree.discard(Interval(-10, 10)) # Same as remove, but no exception on failure
+ >>> tree
+ IntervalTree([Interval(-20, -10), Interval(10, 20)])
+
+ Delete intervals, overlapping a given point::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> tree.remove_overlap(1.1)
+ >>> tree
+ IntervalTree([Interval(-1.1, 1.1)])
+
+ Delete intervals, overlapping an interval::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> tree.remove_overlap(0, 0.5)
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+ >>> tree.remove_overlap(1.7, 1.8)
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+ >>> tree.remove_overlap(1.6, 1.6) # Null interval does nothing
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+ >>> tree.remove_overlap(1.6, 1.5) # Ditto
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+
+ Delete intervals, enveloped in the range::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> tree.remove_envelop(-1.0, 1.5)
+ >>> tree
+ IntervalTree([Interval(-1.1, 1.1), Interval(0.5, 1.7)])
+ >>> tree.remove_envelop(-1.1, 1.5)
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+ >>> tree.remove_envelop(0.5, 1.5)
+ >>> tree
+ IntervalTree([Interval(0.5, 1.7)])
+ >>> tree.remove_envelop(0.5, 1.7)
+ >>> tree
+ IntervalTree()
+
+ Point/interval overlap queries::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> assert tree[-1.1] == set([Interval(-1.1, 1.1)])
+ >>> assert tree.search(1.1) == set([Interval(-0.5, 1.5), Interval(0.5, 1.7)]) # Same as tree[1.1]
+ >>> assert tree[-0.5:0.5] == set([Interval(-0.5, 1.5), Interval(-1.1, 1.1)]) # Interval overlap query
+ >>> assert tree.search(1.5, 1.5) == set() # Same as tree[1.5:1.5]
+ >>> assert tree.search(1.5) == set([Interval(0.5, 1.7)]) # Same as tree[1.5]
+
+ >>> assert tree.search(1.7, 1.8) == set()
+
+ Envelop queries::
+
+ >>> assert tree.search(-0.5, 0.5, strict=True) == set()
+ >>> assert tree.search(-0.4, 1.7, strict=True) == set([Interval(0.5, 1.7)])
+
+ Membership queries::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> Interval(-0.5, 0.5) in tree
+ False
+ >>> Interval(-1.1, 1.1) in tree
+ True
+ >>> Interval(-1.1, 1.1, "x") in tree
+ False
+ >>> tree.overlaps(-1.1)
+ True
+ >>> tree.overlaps(1.7)
+ False
+ >>> tree.overlaps(1.7, 1.8)
+ False
+ >>> tree.overlaps(-1.2, -1.1)
+ False
+ >>> tree.overlaps(-1.2, -1.0)
+ True
+
+ Sizing::
+
+ >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+ >>> len(tree)
+ 3
+ >>> tree.is_empty()
+ False
+ >>> IntervalTree().is_empty()
+ True
+ >>> not tree
+ False
+ >>> not IntervalTree()
+ True
+ >>> print(tree.begin()) # using print() because of floats in Python 2.6
+ -1.1
+ >>> print(tree.end()) # ditto
+ 1.7
+
+ Iteration::
+
+ >>> tree = IntervalTree([Interval(-11, 11), Interval(-5, 15), Interval(5, 17)])
+ >>> [iv.begin for iv in sorted(tree)]
+ [-11, -5, 5]
+ >>> assert tree.items() == set([Interval(-5, 15), Interval(-11, 11), Interval(5, 17)])
+
+ Copy- and typecasting, pickling::
+
+ >>> tree0 = IntervalTree([Interval(0, 1, "x"), Interval(1, 2, ["x"])])
+ >>> tree1 = IntervalTree(tree0) # Shares Interval objects
+ >>> tree2 = tree0.copy() # Shallow copy (same as above, as Intervals are singletons)
+ >>> import pickle
+ >>> tree3 = pickle.loads(pickle.dumps(tree0)) # Deep copy
+ >>> list(tree0[1])[0].data[0] = "y" # affects shallow copies, but not deep copies
+ >>> tree0
+ IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+ >>> tree1
+ IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+ >>> tree2
+ IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+ >>> tree3
+ IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['x'])])
+
+ Equality testing::
+
+ >>> IntervalTree([Interval(0, 1)]) == IntervalTree([Interval(0, 1)])
+ True
+ >>> IntervalTree([Interval(0, 1)]) == IntervalTree([Interval(0, 1, "x")])
+ False
+ """
+ @classmethod
+ def from_tuples(cls, tups):
+ """
+ Create a new IntervalTree from an iterable of 2- or 3-tuples,
+ where the tuple lists begin, end, and optionally data.
+ """
+ ivs = [Interval(*t) for t in tups]
+ return IntervalTree(ivs)
+
+ def __init__(self, intervals=None):
+ """
+ Set up a tree. If intervals is provided, add all the intervals
+ to the tree.
+
+ Completes in O(n*log n) time.
+ """
+ intervals = set(intervals) if intervals is not None else set()
+ for iv in intervals:
+ if iv.is_null():
+ raise ValueError(
+ "IntervalTree: Null Interval objects not allowed in IntervalTree:"
+ " {0}".format(iv)
+ )
+ self.all_intervals = intervals
+ self.top_node = Node.from_intervals(self.all_intervals)
+ self.boundary_table = SortedDict()
+ for iv in self.all_intervals:
+ self._add_boundaries(iv)
+
+ def copy(self):
+ """
+ Construct a new IntervalTree using shallow copies of the
+ intervals in the source tree.
+
+ Completes in O(n*log n) time.
+ :rtype: IntervalTree
+ """
+ return IntervalTree(iv.copy() for iv in self)
+
+ def _add_boundaries(self, interval):
+ """
+ Records the boundaries of the interval in the boundary table.
+ """
+ begin = interval.begin
+ end = interval.end
+ if begin in self.boundary_table:
+ self.boundary_table[begin] += 1
+ else:
+ self.boundary_table[begin] = 1
+
+ if end in self.boundary_table:
+ self.boundary_table[end] += 1
+ else:
+ self.boundary_table[end] = 1
+
+ def _remove_boundaries(self, interval):
+ """
+ Removes the boundaries of the interval from the boundary table.
+ """
+ begin = interval.begin
+ end = interval.end
+ if self.boundary_table[begin] == 1:
+ del self.boundary_table[begin]
+ else:
+ self.boundary_table[begin] -= 1
+
+ if self.boundary_table[end] == 1:
+ del self.boundary_table[end]
+ else:
+ self.boundary_table[end] -= 1
+
+ def add(self, interval):
+ """
+ Adds an interval to the tree, if not already present.
+
+ Completes in O(log n) time.
+ """
+ if interval in self:
+ return
+
+ if interval.is_null():
+ raise ValueError(
+ "IntervalTree: Null Interval objects not allowed in IntervalTree:"
+ " {0}".format(interval)
+ )
+
+ if not self.top_node:
+ self.top_node = Node.from_interval(interval)
+ else:
+ self.top_node = self.top_node.add(interval)
+ self.all_intervals.add(interval)
+ self._add_boundaries(interval)
+ append = add
+
+ def addi(self, begin, end, data=None):
+ """
+ Shortcut for add(Interval(begin, end, data)).
+
+ Completes in O(log n) time.
+ """
+ return self.add(Interval(begin, end, data))
+ appendi = addi
+
+ def update(self, intervals):
+ """
+ Given an iterable of intervals, add them to the tree.
+
+ Completes in O(m*log(n+m), where m = number of intervals to
+ add.
+ """
+ for iv in intervals:
+ self.add(iv)
+
+ def extend(self, intervals):
+ """
+ Deprecated: Replaced by update().
+ """
+ warn("IntervalTree.extend() has been deprecated. Consider using update() instead", DeprecationWarning)
+ self.update(intervals)
+
+ def remove(self, interval):
+ """
+ Removes an interval from the tree, if present. If not, raises
+ ValueError.
+
+ Completes in O(log n) time.
+ """
+ #self.verify()
+ if interval not in self:
+ #print(self.all_intervals)
+ raise ValueError
+ self.top_node = self.top_node.remove(interval)
+ self.all_intervals.remove(interval)
+ self._remove_boundaries(interval)
+ #self.verify()
+
+ def removei(self, begin, end, data=None):
+ """
+ Shortcut for remove(Interval(begin, end, data)).
+
+ Completes in O(log n) time.
+ """
+ return self.remove(Interval(begin, end, data))
+
+ def discard(self, interval):
+ """
+ Removes an interval from the tree, if present. If not, does
+ nothing.
+
+ Completes in O(log n) time.
+ """
+ if interval not in self:
+ return
+ self.all_intervals.discard(interval)
+ self.top_node = self.top_node.discard(interval)
+ self._remove_boundaries(interval)
+
+ def discardi(self, begin, end, data=None):
+ """
+ Shortcut for discard(Interval(begin, end, data)).
+
+ Completes in O(log n) time.
+ """
+ return self.discard(Interval(begin, end, data))
+
+ def difference(self, other):
+ """
+ Returns a new tree, comprising all intervals in self but not
+ in other.
+ """
+ ivs = set()
+ for iv in self:
+ if iv not in other:
+ ivs.add(iv)
+ return IntervalTree(ivs)
+
+ def difference_update(self, other):
+ """
+ Removes all intervals in other from self.
+ """
+ for iv in other:
+ self.discard(iv)
+
+ def union(self, other):
+ """
+ Returns a new tree, comprising all intervals from self
+ and other.
+ """
+ return IntervalTree(set(self).union(other))
+
+ def intersection(self, other):
+ """
+ Returns a new tree of all intervals common to both self and
+ other.
+ """
+ ivs = set()
+ shorter, longer = sorted([self, other], key=len)
+ for iv in shorter:
+ if iv in longer:
+ ivs.add(iv)
+ return IntervalTree(ivs)
+
+ def intersection_update(self, other):
+ """
+ Removes intervals from self unless they also exist in other.
+ """
+ for iv in self:
+ if iv not in other:
+ self.remove(iv)
+
+ def symmetric_difference(self, other):
+ """
+ Return a tree with elements only in self or other but not
+ both.
+ """
+ if not isinstance(other, set): other = set(other)
+ me = set(self)
+ ivs = me - other + (other - me)
+ return IntervalTree(ivs)
+
+ def symmetric_difference_update(self, other):
+ """
+ Throws out all intervals except those only in self or other,
+ not both.
+ """
+ other = set(other)
+ for iv in self:
+ if iv in other:
+ self.remove(iv)
+ other.remove(iv)
+ self.update(other)
+
+ def remove_overlap(self, begin, end=None):
+ """
+ Removes all intervals overlapping the given point or range.
+
+ Completes in O((r+m)*log n) time, where:
+ * n = size of the tree
+ * m = number of matches
+ * r = size of the search range (this is 1 for a point)
+ """
+ hitlist = self.search(begin, end)
+ for iv in hitlist:
+ self.remove(iv)
+
+ def remove_envelop(self, begin, end):
+ """
+ Removes all intervals completely enveloped in the given range.
+
+ Completes in O((r+m)*log n) time, where:
+ * n = size of the tree
+ * m = number of matches
+ * r = size of the search range (this is 1 for a point)
+ """
+ hitlist = self.search(begin, end, strict=True)
+ for iv in hitlist:
+ self.remove(iv)
+
+ def chop(self, begin, end, datafunc=None):
+ """
+ Like remove_envelop(), but trims back Intervals hanging into
+ the chopped area so that nothing overlaps.
+ """
+ insertions = set()
+ begin_hits = [iv for iv in self[begin] if iv.begin < begin]
+ end_hits = [iv for iv in self[end] if iv.end > end]
+
+ if datafunc:
+ for iv in begin_hits:
+ insertions.add(Interval(iv.begin, begin, datafunc(iv, True)))
+ for iv in end_hits:
+ insertions.add(Interval(end, iv.end, datafunc(iv, False)))
+ else:
+ for iv in begin_hits:
+ insertions.add(Interval(iv.begin, begin, iv.data))
+ for iv in end_hits:
+ insertions.add(Interval(end, iv.end, iv.data))
+
+ self.remove_envelop(begin, end)
+ self.difference_update(begin_hits)
+ self.difference_update(end_hits)
+ self.update(insertions)
+
+ def slice(self, point, datafunc=None):
+ """
+ Split Intervals that overlap point into two new Intervals. if
+ specified, uses datafunc(interval, islower=True/False) to
+ set the data field of the new Intervals.
+ :param point: where to slice
+ :param datafunc(interval, isupper): callable returning a new
+ value for the interval's data field
+ """
+ hitlist = set(iv for iv in self[point] if iv.begin < point)
+ insertions = set()
+ if datafunc:
+ for iv in hitlist:
+ insertions.add(Interval(iv.begin, point, datafunc(iv, True)))
+ insertions.add(Interval(point, iv.end, datafunc(iv, False)))
+ else:
+ for iv in hitlist:
+ insertions.add(Interval(iv.begin, point, iv.data))
+ insertions.add(Interval(point, iv.end, iv.data))
+ self.difference_update(hitlist)
+ self.update(insertions)
+
+ def clear(self):
+ """
+ Empties the tree.
+
+ Completes in O(1) tine.
+ """
+ self.__init__()
+
+ def find_nested(self):
+ """
+ Returns a dictionary mapping parent intervals to sets of
+ intervals overlapped by and contained in the parent.
+
+ Completes in O(n^2) time.
+ :rtype: dict of [Interval, set of Interval]
+ """
+ result = {}
+
+ def add_if_nested():
+ if parent.contains_interval(child):
+ if parent not in result:
+ result[parent] = set()
+ result[parent].add(child)
+
+ long_ivs = sorted(self.all_intervals, key=Interval.length, reverse=True)
+ for i, parent in enumerate(long_ivs):
+ for child in long_ivs[i + 1:]:
+ add_if_nested()
+ return result
+
+ def overlaps(self, begin, end=None):
+ """
+ Returns whether some interval in the tree overlaps the given
+ point or range.
+
+ Completes in O(r*log n) time, where r is the size of the
+ search range.
+ :rtype: bool
+ """
+ if end is not None:
+ return self.overlaps_range(begin, end)
+ elif isinstance(begin, Number):
+ return self.overlaps_point(begin)
+ else:
+ return self.overlaps_range(begin.begin, begin.end)
+
+ def overlaps_point(self, p):
+ """
+ Returns whether some interval in the tree overlaps p.
+
+ Completes in O(log n) time.
+ :rtype: bool
+ """
+ if self.is_empty():
+ return False
+ return bool(self.top_node.contains_point(p))
+
+ def overlaps_range(self, begin, end):
+ """
+ Returns whether some interval in the tree overlaps the given
+ range.
+
+ Completes in O(r*log n) time, where r is the range length and n
+ is the table size.
+ :rtype: bool
+ """
+ if self.is_empty():
+ return False
+ elif self.overlaps_point(begin):
+ return True
+ return any(
+ self.overlaps_point(bound)
+ for bound in self.boundary_table
+ if begin <= bound < end
+ )
+
+ def split_overlaps(self):
+ """
+ Finds all intervals with overlapping ranges and splits them
+ along the range boundaries.
+
+ Completes in worst-case O(n^2*log n) time (many interval
+ boundaries are inside many intervals), best-case O(n*log n)
+ time (small number of overlaps << n per interval).
+ """
+ if not self:
+ return
+ if len(self.boundary_table) == 2:
+ return
+
+ bounds = sorted(self.boundary_table) # get bound locations
+
+ new_ivs = set()
+ for lbound, ubound in zip(bounds[:-1], bounds[1:]):
+ for iv in self[lbound]:
+ new_ivs.add(Interval(lbound, ubound, iv.data))
+
+ self.__init__(new_ivs)
+
+ def items(self):
+ """
+ Constructs and returns a set of all intervals in the tree.
+
+ Completes in O(n) time.
+ :rtype: set of Interval
+ """
+ return set(self.all_intervals)
+
+ def is_empty(self):
+ """
+ Returns whether the tree is empty.
+
+ Completes in O(1) time.
+ :rtype: bool
+ """
+ return 0 == len(self)
+
+ def search(self, begin, end=None, strict=False):
+ """
+ Returns a set of all intervals overlapping the given range. Or,
+ if strict is True, returns the set of all intervals fully
+ contained in the range [begin, end].
+
+ Completes in O(m + k*log n) time, where:
+ * n = size of the tree
+ * m = number of matches
+ * k = size of the search range (this is 1 for a point)
+ :rtype: set of Interval
+ """
+ root = self.top_node
+ if not root:
+ return set()
+ if end is None:
+ try:
+ iv = begin
+ return self.search(iv.begin, iv.end, strict=strict)
+ except:
+ return root.search_point(begin, set())
+ elif begin >= end:
+ return set()
+ else:
+ result = root.search_point(begin, set())
+
+ boundary_table = self.boundary_table
+ bound_begin = boundary_table.bisect_left(begin)
+ bound_end = boundary_table.bisect_left(end) # exclude final end bound
+ result.update(root.search_overlap(
+ # slice notation is slightly slower
+ boundary_table.iloc[index] for index in xrange(bound_begin, bound_end)
+ ))
+
+ # TODO: improve strict search to use node info instead of less-efficient filtering
+ if strict:
+ result = set(
+ iv for iv in result
+ if iv.begin >= begin and iv.end <= end
+ )
+ return result
+
+ def begin(self):
+ """
+ Returns the lower bound of the first interval in the tree.
+
+ Completes in O(n) time.
+ :rtype: Number
+ """
+ if not self.boundary_table:
+ return 0
+ return min(self.boundary_table)
+
+ def end(self):
+ """
+ Returns the upper bound of the last interval in the tree.
+
+ Completes in O(n) time.
+ :rtype: Number
+ """
+ if not self.boundary_table:
+ return 0
+ return max(self.boundary_table)
+
+ def print_structure(self, tostring=False):
+ """
+ ## FOR DEBUGGING ONLY ##
+ Pretty-prints the structure of the tree.
+ If tostring is true, prints nothing and returns a string.
+ :rtype: None or str
+ """
+ if self.top_node:
+ return self.top_node.print_structure(tostring=tostring)
+ else:
+ result = "<empty IntervalTree>"
+ if not tostring:
+ print(result)
+ else:
+ return result
+
+ def verify(self):
+ """
+ ## FOR DEBUGGING ONLY ##
+ Checks the table to ensure that the invariants are held.
+ """
+ if self.all_intervals:
+ ## top_node.all_children() == self.all_intervals
+ try:
+ assert self.top_node.all_children() == self.all_intervals
+ except AssertionError as e:
+ print(
+ 'Error: the tree and the membership set are out of sync!'
+ )
+ tivs = set(self.top_node.all_children())
+ print('top_node.all_children() - all_intervals:')
+ pprint(tivs - self.all_intervals)
+ print('all_intervals - top_node.all_children():')
+ pprint(self.all_intervals - tivs)
+ raise e
+
+ ## All members are Intervals
+ for iv in self:
+ assert isinstance(iv, Interval), (
+ "Error: Only Interval objects allowed in IntervalTree:"
+ " {0}".format(iv)
+ )
+
+ ## No null intervals
+ for iv in self:
+ assert not iv.is_null(), (
+ "Error: Null Interval objects not allowed in IntervalTree:"
+ " {0}".format(iv)
+ )
+
+ ## Reconstruct boundary_table
+ bound_check = {}
+ for iv in self:
+ if iv.begin in bound_check:
+ bound_check[iv.begin] += 1
+ else:
+ bound_check[iv.begin] = 1
+ if iv.end in bound_check:
+ bound_check[iv.end] += 1
+ else:
+ bound_check[iv.end] = 1
+
+ ## Reconstructed boundary table (bound_check) ==? boundary_table
+ assert set(self.boundary_table.keys()) == set(bound_check.keys()),\
+ 'Error: boundary_table is out of sync with ' \
+ 'the intervals in the tree!'
+
+ # For efficiency reasons this should be iteritems in Py2, but we
+ # don't care much for efficiency in debug methods anyway.
+ for key, val in self.boundary_table.items():
+ assert bound_check[key] == val, \
+ 'Error: boundary_table[{0}] should be {1},' \
+ ' but is {2}!'.format(
+ key, bound_check[key], val)
+
+ ## Internal tree structure
+ self.top_node.verify(set())
+ else:
+ ## Verify empty tree
+ assert not self.boundary_table, \
+ "Error: boundary table should be empty!"
+ assert self.top_node is None, \
+ "Error: top_node isn't None!"
+
+ def score(self, full_report=False):
+ """
+ Returns a number between 0 and 1, indicating how suboptimal the tree
+ is. The lower, the better. Roughly, this number represents the
+ fraction of flawed Intervals in the tree.
+ :rtype: float
+ """
+ if len(self) <= 2:
+ return 0.0
+
+ n = len(self)
+ m = self.top_node.count_nodes()
+
+ def s_center_score():
+ """
+ Returns a normalized score, indicating roughly how many times
+ intervals share s_center with other intervals. Output is full-scale
+ from 0 to 1.
+ :rtype: float
+ """
+ raw = n - m
+ maximum = n - 1
+ return raw / float(maximum)
+
+ report = {
+ "depth": self.top_node.depth_score(n, m),
+ "s_center": s_center_score(),
+ }
+ cumulative = max(report.values())
+ report["_cumulative"] = cumulative
+ if full_report:
+ return report
+ return cumulative
+
+ def __getitem__(self, index):
+ """
+ Returns a set of all intervals overlapping the given index or
+ slice.
+
+ Completes in O(k * log(n) + m) time, where:
+ * n = size of the tree
+ * m = number of matches
+ * k = size of the search range (this is 1 for a point)
+ :rtype: set of Interval
+ """
+ try:
+ start, stop = index.start, index.stop
+ if start is None:
+ start = self.begin()
+ if stop is None:
+ return set(self)
+ if stop is None:
+ stop = self.end()
+ return self.search(start, stop)
+ except AttributeError:
+ return self.search(index)
+
+ def __setitem__(self, index, value):
+ """
+ Adds a new interval to the tree. A shortcut for
+ add(Interval(index.start, index.stop, value)).
+
+ If an identical Interval object with equal range and data
+ already exists, does nothing.
+
+ Completes in O(log n) time.
+ """
+ self.addi(index.start, index.stop, value)
+
+ def __delitem__(self, point):
+ """
+ Delete all items overlapping point.
+ """
+ self.remove_overlap(point)
+
+ def __contains__(self, item):
+ """
+ Returns whether item exists as an Interval in the tree.
+ This method only returns True for exact matches; for
+ overlaps, see the overlaps() method.
+
+ Completes in O(1) time.
+ :rtype: bool
+ """
+ # Removed point-checking code; it might trick the user into
+ # thinking that this is O(1), which point-checking isn't.
+ #if isinstance(item, Interval):
+ return item in self.all_intervals
+ #else:
+ # return self.contains_point(item)
+
+ def containsi(self, begin, end, data=None):
+ """
+ Shortcut for (Interval(begin, end, data) in tree).
+
+ Completes in O(1) time.
+ :rtype: bool
+ """
+ return Interval(begin, end, data) in self
+
+ def __iter__(self):
+ """
+ Returns an iterator over all the intervals in the tree.
+
+ Completes in O(1) time.
+ :rtype: collections.Iterable[Interval]
+ """
+ return self.all_intervals.__iter__()
+ iter = __iter__
+
+ def __len__(self):
+ """
+ Returns how many intervals are in the tree.
+
+ Completes in O(1) time.
+ :rtype: int
+ """
+ return len(self.all_intervals)
+
+ def __eq__(self, other):
+ """
+ Whether two IntervalTrees are equal.
+
+ Completes in O(n) time if sizes are equal; O(1) time otherwise.
+ :rtype: bool
+ """
+ return (
+ isinstance(other, IntervalTree) and
+ self.all_intervals == other.all_intervals
+ )
+
+ def __repr__(self):
+ """
+ :rtype: str
+ """
+ ivs = sorted(self)
+ if not ivs:
+ return "IntervalTree()"
+ else:
+ return "IntervalTree({0})".format(ivs)
+
+ __str__ = __repr__
+
+ def __reduce__(self):
+ """
+ For pickle-ing.
+ :rtype: tuple
+ """
+ return IntervalTree, (sorted(self.all_intervals),)
diff --git a/src/intervaltree/node.py b/src/intervaltree/node.py
new file mode 100755
index 0000000..e9d9170
--- /dev/null
+++ b/src/intervaltree/node.py
@@ -0,0 +1,593 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Core logic: internal tree nodes.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications Copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from operator import attrgetter
+from math import floor, log
+
+
+def l2(num):
+ """
+ log base 2
+ :rtype real
+ """
+ return log(num, 2)
+
+
+class Node(object):
+ def __init__(self,
+ x_center=None,
+ s_center=set(),
+ left_node=None,
+ right_node=None):
+ self.x_center = x_center
+ self.s_center = set(s_center)
+ self.left_node = left_node
+ self.right_node = right_node
+ self.depth = 0 # will be set when rotated
+ self.balance = 0 # ditto
+ self.rotate()
+
+ @classmethod
+ def from_interval(cls, interval):
+ """
+ :rtype : Node
+ """
+ center = interval.begin
+ return Node(center, [interval])
+
+ @classmethod
+ def from_intervals(cls, intervals):
+ """
+ :rtype : Node
+ """
+ if not intervals:
+ return None
+ node = Node()
+ node = node.init_from_sorted(sorted(intervals))
+ return node
+
+ def init_from_sorted(self, intervals):
+ if not intervals:
+ return None
+ center_iv = intervals[len(intervals) // 2]
+ self.x_center = center_iv.begin
+ self.s_center = set()
+ s_left = []
+ s_right = []
+ for k in intervals:
+ if k.end <= self.x_center:
+ s_left.append(k)
+ elif k.begin > self.x_center:
+ s_right.append(k)
+ else:
+ self.s_center.add(k)
+ self.left_node = Node.from_intervals(s_left)
+ self.right_node = Node.from_intervals(s_right)
+ return self.rotate()
+
+ def center_hit(self, interval):
+ """Returns whether interval overlaps self.x_center."""
+ return interval.contains_point(self.x_center)
+
+ def hit_branch(self, interval):
+ """
+ Assuming not center_hit(interval), return which branch
+ (left=0, right=1) interval is in.
+ """
+ return interval.begin > self.x_center
+
+ def refresh_balance(self):
+ """
+ Recalculate self.balance and self.depth based on child node values.
+ """
+ left_depth = self.left_node.depth if self.left_node else 0
+ right_depth = self.right_node.depth if self.right_node else 0
+ self.depth = 1 + max(left_depth, right_depth)
+ self.balance = right_depth - left_depth
+
+ def compute_depth(self):
+ """
+ Recursively computes true depth of the subtree. Should only
+ be needed for debugging. Unless something is wrong, the
+ depth field should reflect the correct depth of the subtree.
+ """
+ left_depth = self.left_node.compute_depth() if self.left_node else 0
+ right_depth = self.right_node.compute_depth() if self.right_node else 0
+ return 1 + max(left_depth, right_depth)
+
+ def rotate(self):
+ """
+ Does rotating, if necessary, to balance this node, and
+ returns the new top node.
+ """
+ self.refresh_balance()
+ if abs(self.balance) < 2:
+ return self
+ # balance > 0 is the heavy side
+ my_heavy = self.balance > 0
+ child_heavy = self[my_heavy].balance > 0
+ if my_heavy == child_heavy or self[my_heavy].balance == 0:
+ ## Heavy sides same
+ # self save
+ # save -> 1 self
+ # 1
+ #
+ ## Heavy side balanced
+ # self save save
+ # save -> 1 self -> 1 self.rot()
+ # 1 2 2
+ return self.srotate()
+ else:
+ return self.drotate()
+
+ def srotate(self):
+ """Single rotation. Assumes that balance is +-2."""
+ # self save save
+ # save 3 -> 1 self -> 1 self.rot()
+ # 1 2 2 3
+ #
+ # self save save
+ # 3 save -> self 1 -> self.rot() 1
+ # 2 1 3 2
+
+ #assert(self.balance != 0)
+ heavy = self.balance > 0
+ light = not heavy
+ save = self[heavy]
+ #print("srotate: bal={},{}".format(self.balance, save.balance))
+ #self.print_structure()
+ self[heavy] = save[light] # 2
+ #assert(save[light])
+ save[light] = self.rotate() # Needed to ensure the 2 and 3 are balanced under new subnode
+
+ # Some intervals may overlap both self.x_center and save.x_center
+ # Promote those to the new tip of the tree
+ promotees = [iv for iv in save[light].s_center if save.center_hit(iv)]
+ if promotees:
+ for iv in promotees:
+ save[light] = save[light].remove(iv) # may trigger pruning
+ # TODO: Use Node.add() here, to simplify future balancing improvements.
+ # For now, this is the same as augmenting save.s_center, but that may
+ # change.
+ save.s_center.update(promotees)
+ save.refresh_balance()
+ return save
+
+ def drotate(self):
+ # First rotation
+ my_heavy = self.balance > 0
+ self[my_heavy] = self[my_heavy].srotate()
+ self.refresh_balance()
+
+ # Second rotation
+ result = self.srotate()
+
+ return result
+
+ def add(self, interval):
+ """
+ Returns self after adding the interval and balancing.
+ """
+ if self.center_hit(interval):
+ self.s_center.add(interval)
+ return self
+ else:
+ direction = self.hit_branch(interval)
+ if not self[direction]:
+ self[direction] = Node.from_interval(interval)
+ self.refresh_balance()
+ return self
+ else:
+ self[direction] = self[direction].add(interval)
+ return self.rotate()
+
+ def remove(self, interval):
+ """
+ Returns self after removing the interval and balancing.
+
+ If interval is not present, raise ValueError.
+ """
+ # since this is a list, called methods can set this to [1],
+ # making it true
+ done = []
+ return self.remove_interval_helper(interval, done, should_raise_error=True)
+
+ def discard(self, interval):
+ """
+ Returns self after removing interval and balancing.
+
+ If interval is not present, do nothing.
+ """
+ done = []
+ return self.remove_interval_helper(interval, done, should_raise_error=False)
+
+ def remove_interval_helper(self, interval, done, should_raise_error):
+ """
+ Returns self after removing interval and balancing.
+ If interval doesn't exist, raise ValueError.
+
+ This method may set done to [1] to tell all callers that
+ rebalancing has completed.
+
+ See Eternally Confuzzled's jsw_remove_r function (lines 1-32)
+ in his AVL tree article for reference.
+ """
+ #trace = interval.begin == 347 and interval.end == 353
+ #if trace: print('\nRemoving from {} interval {}'.format(
+ # self.x_center, interval))
+ if self.center_hit(interval):
+ #if trace: print('Hit at {}'.format(self.x_center))
+ if not should_raise_error and interval not in self.s_center:
+ done.append(1)
+ #if trace: print('Doing nothing.')
+ return self
+ try:
+ # raises error if interval not present - this is
+ # desired.
+ self.s_center.remove(interval)
+ except:
+ self.print_structure()
+ raise KeyError(interval)
+ if self.s_center: # keep this node
+ done.append(1) # no rebalancing necessary
+ #if trace: print('Removed, no rebalancing.')
+ return self
+
+ # If we reach here, no intervals are left in self.s_center.
+ # So, prune self.
+ return self.prune()
+ else: # interval not in s_center
+ direction = self.hit_branch(interval)
+
+ if not self[direction]:
+ if should_raise_error:
+ raise ValueError
+ done.append(1)
+ return self
+
+ #if trace:
+ # print('Descending to {} branch'.format(
+ # ['left', 'right'][direction]
+ # ))
+ self[direction] = self[direction].remove_interval_helper(interval, done, should_raise_error)
+
+ # Clean up
+ if not done:
+ #if trace:
+ # print('Rotating {}'.format(self.x_center))
+ # self.print_structure()
+ return self.rotate()
+ return self
+
+ def search_overlap(self, point_list):
+ """
+ Returns all intervals that overlap the point_list.
+ """
+ result = set()
+ for j in point_list:
+ self.search_point(j, result)
+ return result
+
+ def search_point(self, point, result):
+ """
+ Returns all intervals that contain point.
+ """
+ for k in self.s_center:
+ if k.begin <= point < k.end:
+ result.add(k)
+ if point < self.x_center and self[0]:
+ return self[0].search_point(point, result)
+ elif point > self.x_center and self[1]:
+ return self[1].search_point(point, result)
+ return result
+
+ def prune(self):
+ """
+ On a subtree where the root node's s_center is empty,
+ return a new subtree with no empty s_centers.
+ """
+ if not self[0] or not self[1]: # if I have an empty branch
+ direction = not self[0] # graft the other branch here
+ #if trace:
+ # print('Grafting {} branch'.format(
+ # 'right' if direction else 'left'))
+
+ result = self[direction]
+ #if result: result.verify()
+ return result
+ else:
+ # Replace the root node with the greatest predecessor.
+ heir, self[0] = self[0].pop_greatest_child()
+ #if trace:
+ # print('Replacing {} with {}.'.format(
+ # self.x_center, heir.x_center
+ # ))
+ # print('Removed greatest predecessor:')
+ # self.print_structure()
+
+ #if self[0]: self[0].verify()
+ #if self[1]: self[1].verify()
+
+ # Set up the heir as the new root node
+ (heir[0], heir[1]) = (self[0], self[1])
+ #if trace: print('Setting up the heir:')
+ #if trace: heir.print_structure()
+
+ # popping the predecessor may have unbalanced this node;
+ # fix it
+ heir.refresh_balance()
+ heir = heir.rotate()
+ #heir.verify()
+ #if trace: print('Rotated the heir:')
+ #if trace: heir.print_structure()
+ return heir
+
+ def pop_greatest_child(self):
+ """
+ Used when pruning a node with both a left and a right branch.
+ Returns (greatest_child, node), where:
+ * greatest_child is a new node to replace the removed node.
+ * node is the subtree after:
+ - removing the greatest child
+ - balancing
+ - moving overlapping nodes into greatest_child
+
+ Assumes that self.s_center is not empty.
+
+ See Eternally Confuzzled's jsw_remove_r function (lines 34-54)
+ in his AVL tree article for reference.
+ """
+ #print('Popping from {}'.format(self.x_center))
+ if not self.right_node: # This node is the greatest child.
+ # To reduce the chances of an overlap with a parent, return
+ # a child node containing the smallest possible number of
+ # intervals, as close as possible to the maximum bound.
+ ivs = sorted(self.s_center, key=attrgetter('end', 'begin'))
+ max_iv = ivs.pop()
+ new_x_center = self.x_center
+ while ivs:
+ next_max_iv = ivs.pop()
+ if next_max_iv.end == max_iv.end: continue
+ new_x_center = max(new_x_center, next_max_iv.end)
+ def get_new_s_center():
+ for iv in self.s_center:
+ if iv.contains_point(new_x_center): yield iv
+
+ # Create a new node with the largest x_center possible.
+ child = Node.from_intervals(get_new_s_center())
+ # [iv for iv in self.s_center if iv.contains_point(child_x_center)]
+ # )
+ child.x_center = new_x_center
+ self.s_center -= child.s_center
+
+ #print('Pop hit! Returning child = {}'.format(
+ # child.print_structure(tostring=True)
+ # ))
+ #assert not child[0]
+ #assert not child[1]
+
+ if self.s_center:
+ #print(' and returning newnode = {}'.format( self ))
+ #self.verify()
+ return child, self
+ else:
+ #print(' and returning newnode = {}'.format( self[0] ))
+ #if self[0]: self[0].verify()
+ return child, self[0] # Rotate left child up
+
+ else:
+ #print('Pop descent to {}'.format(self[1].x_center))
+ (greatest_child, self[1]) = self[1].pop_greatest_child()
+ self.refresh_balance()
+ new_self = self.rotate()
+
+ # Move any overlaps into greatest_child
+ for iv in set(new_self.s_center):
+ if iv.contains_point(greatest_child.x_center):
+ new_self.s_center.remove(iv)
+ greatest_child.add(iv)
+
+ #print('Pop Returning child = {}'.format(
+ # greatest_child.print_structure(tostring=True)
+ # ))
+ if new_self.s_center:
+ #print('and returning newnode = {}'.format(
+ # new_self.print_structure(tostring=True)
+ # ))
+ #new_self.verify()
+ return greatest_child, new_self
+ else:
+ new_self = new_self.prune()
+ #print('and returning prune = {}'.format(
+ # new_self.print_structure(tostring=True)
+ # ))
+ #if new_self: new_self.verify()
+ return greatest_child, new_self
+
+ def contains_point(self, p):
+ """
+ Returns whether this node or a child overlaps p.
+ """
+ for iv in self.s_center:
+ if iv.contains_point(p):
+ return True
+ branch = self[p > self.x_center]
+ return branch and branch.contains_point(p)
+
+ def all_children(self):
+ return self.all_children_helper(set())
+
+ def all_children_helper(self, result):
+ result.update(self.s_center)
+ if self[0]:
+ self[0].all_children_helper(result)
+ if self[1]:
+ self[1].all_children_helper(result)
+ return result
+
+ def verify(self, parents=set()):
+ """
+ ## DEBUG ONLY ##
+ Recursively ensures that the invariants of an interval subtree
+ hold.
+ """
+ assert(isinstance(self.s_center, set))
+
+ bal = self.balance
+ assert abs(bal) < 2, \
+ "Error: Rotation should have happened, but didn't! \n{}".format(
+ self.print_structure(tostring=True)
+ )
+ self.refresh_balance()
+ assert bal == self.balance, \
+ "Error: self.balance not set correctly! \n{}".format(
+ self.print_structure(tostring=True)
+ )
+
+ assert self.s_center, \
+ "Error: s_center is empty! \n{}".format(
+ self.print_structure(tostring=True)
+ )
+ for iv in self.s_center:
+ assert hasattr(iv, 'begin')
+ assert hasattr(iv, 'end')
+ assert iv.begin < iv.end
+ assert iv.overlaps(self.x_center)
+ for parent in sorted(parents):
+ assert not iv.contains_point(parent), \
+ "Error: Overlaps ancestor ({})! \n{}\n\n{}".format(
+ parent, iv, self.print_structure(tostring=True)
+ )
+ if self[0]:
+ assert self[0].x_center < self.x_center, \
+ "Error: Out-of-order left child! {}".format(self.x_center)
+ self[0].verify(parents.union([self.x_center]))
+ if self[1]:
+ assert self[1].x_center > self.x_center, \
+ "Error: Out-of-order right child! {}".format(self.x_center)
+ self[1].verify(parents.union([self.x_center]))
+
+ def __getitem__(self, index):
+ """
+ Returns the left child if input is equivalent to False, or
+ the right side otherwise.
+ """
+ if index:
+ return self.right_node
+ else:
+ return self.left_node
+
+ def __setitem__(self, key, value):
+ """Sets the left (0) or right (1) child."""
+ if key:
+ self.right_node = value
+ else:
+ self.left_node = value
+
+ def __str__(self):
+ """
+ Shows info about this node.
+
+ Since Nodes are internal data structures not revealed to the
+ user, I'm not bothering to make this copy-paste-executable as a
+ constructor.
+ """
+ return "Node<{0}, depth={1}, balance={2}>".format(
+ self.x_center,
+ self.depth,
+ self.balance
+ )
+ #fieldcount = 'c_count,has_l,has_r = <{}, {}, {}>'.format(
+ # len(self.s_center),
+ # bool(self.left_node),
+ # bool(self.right_node)
+ #)
+ #fields = [self.x_center, self.balance, fieldcount]
+ #return "Node({}, b={}, {})".format(*fields)
+
+ def count_nodes(self):
+ """
+ Count the number of Nodes in this subtree.
+ :rtype: int
+ """
+ count = 1
+ if self.left_node:
+ count += self.left_node.count_nodes()
+ if self.right_node:
+ count += self.right_node.count_nodes()
+ return count
+
+ def depth_score(self, n, m):
+ """
+ Calculates flaws in balancing the tree.
+ :param n: size of tree
+ :param m: number of Nodes in tree
+ :rtype: real
+ """
+ if n == 0:
+ return 0.0
+
+ # dopt is the optimal maximum depth of the tree
+ dopt = 1 + int(floor(l2(m)))
+ f = 1 / float(1 + n - dopt)
+ return f * self.depth_score_helper(1, dopt)
+
+ def depth_score_helper(self, d, dopt):
+ """
+ Gets a weighted count of the number of Intervals deeper than dopt.
+ :param d: current depth, starting from 0
+ :param dopt: optimal maximum depth of a leaf Node
+ :rtype: real
+ """
+ # di is how may levels deeper than optimal d is
+ di = d - dopt
+ if di > 0:
+ count = di * len(self.s_center)
+ else:
+ count = 0
+ if self.right_node:
+ count += self.right_node.depth_score_helper(d + 1, dopt)
+ if self.left_node:
+ count += self.left_node.depth_score_helper(d + 1, dopt)
+ return count
+
+ def print_structure(self, indent=0, tostring=False):
+ """
+ For debugging.
+ """
+ nl = '\n'
+ sp = indent * ' '
+
+ rlist = [str(self) + nl]
+ if self.s_center:
+ for iv in sorted(self.s_center):
+ rlist.append(sp + ' ' + repr(iv) + nl)
+ if self.left_node:
+ rlist.append(sp + '<: ') # no CR
+ rlist.append(self.left_node.print_structure(indent + 1, True))
+ if self.right_node:
+ rlist.append(sp + '>: ') # no CR
+ rlist.append(self.right_node.print_structure(indent + 1, True))
+ result = ''.join(rlist)
+ if tostring:
+ return result
+ else:
+ print(result)
diff --git a/src/long_spanning_reads.cpp b/src/long_spanning_reads.cpp
index 598e4a9..6af43bc 100644
--- a/src/long_spanning_reads.cpp
+++ b/src/long_spanning_reads.cpp
@@ -13,6 +13,8 @@
#include <cassert>
#include <cstdio>
+#include <boost/thread.hpp>
+
#include <vector>
#include <string>
#include <map>
@@ -31,8 +33,6 @@
#include <seqan/modifier.h>
#include <getopt.h>
-#include <boost/thread.hpp>
-
#include "common.h"
#include "utils.h"
#include "bwt_map.h"
diff --git a/src/map2gtf.cpp b/src/map2gtf.cpp
index 8e23a51..cdf937b 100644
--- a/src/map2gtf.cpp
+++ b/src/map2gtf.cpp
@@ -69,10 +69,6 @@ GffTranscript::GffTranscript(const std::string& tline): exons(1),
Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
gtf_fname_(gtf_fname), in_fname_(in_fname), out_sam_header_(NULL), refSeqTable_(true)
{
- /*
- gtf_fhandle_ = fopen(gtf_fname_.c_str(), "r");
- if (gtf_fhandle_ == NULL)
- */
tlststream.open(gtf_fname_.c_str(), std::ios::in);
if (!tlststream.good())
{
@@ -95,8 +91,6 @@ Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
}
in_sam_header_ = in_fhandle_->header;
std::cout << "Reading the transcript data: " << gtf_fname_ << std::endl;
- //gtfReader_.init(gtf_fhandle_, true); //only recognizable transcripts will be loaded
- //gtfReader_.readAll();
std::string tline;
while (std::getline(tlststream, tline)) {
@@ -114,13 +108,6 @@ Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
Map2GTF::~Map2GTF()
{
std::cout << "map2gtf has completed. Cleaning up." << std::endl;
- /*
- if (gtf_fhandle_ != NULL && fclose(gtf_fhandle_))
- {
- std::cerr << "Warning: Error closing annotation: " << gtf_fname_
- << std::endl;
- }
- */
if (in_fhandle_ != NULL)
{
samclose(in_fhandle_);
diff --git a/src/reads.h b/src/reads.h
index 8e14310..5360225 100644
--- a/src/reads.h
+++ b/src/reads.h
@@ -16,15 +16,9 @@
#include <boost/shared_ptr.hpp>
#include <seqan/sequence.h>
#include "common.h"
-//#include "QReadData.h"
-
using std::string;
-
-
-
-
void reverse_complement(string& seq);
string str_convert_color_to_bp(const string& color);
seqan::String<char> convert_color_to_bp(char base, const seqan::String<char>& color);
@@ -251,9 +245,7 @@ struct GetReadProc {
if (rdata->matenum==1) bamrec.set_flag(BAM_FREAD1);
else bamrec.set_flag(BAM_FREAD2);
}
- //if (found && um_code && !rdata->trashCode) {
- //rdata->trashCode=um_code;
- //}
+
if (rdata->trashCode) {
//multi-mapped reads did not really QC-fail
//should also not be written to unmapped.bam
diff --git a/src/segment_juncs.cpp b/src/segment_juncs.cpp
index 2405c05..eaf5db7 100644
--- a/src/segment_juncs.cpp
+++ b/src/segment_juncs.cpp
@@ -13,6 +13,7 @@
#include <cassert>
#include <cstdio>
+#include <boost/thread.hpp>
#include <vector>
#include <string>
#include <map>
@@ -28,8 +29,6 @@
#include <seqan/file.h>
#include <getopt.h>
-#include <boost/thread.hpp>
-
#include "common.h"
#include "utils.h"
#include "bwt_map.h"
@@ -67,8 +66,7 @@ void get_seqs(istream& ref_stream,
bool keep_seqs = true)
{
while(ref_stream.good() &&
- !ref_stream.eof())
- {
+ !ref_stream.eof()) {
RefSequenceTable::Sequence* ref_str = new RefSequenceTable::Sequence();
string name;
readMeta(ref_stream, name, Fasta());
@@ -76,14 +74,17 @@ void get_seqs(istream& ref_stream,
if (space_pos != string::npos)
{
name.resize(space_pos);
- }
+ }
+ if (name.size()>0) {
fprintf(stderr, "\tLoading %s...", name.c_str());
- seqan::read(ref_stream, *ref_str, Fasta());
- fprintf(stderr, "done\n");
- rt.get_id(name, keep_seqs ? ref_str : NULL, 0);
- if (!keep_seqs)
- delete ref_str;
+ fflush(stderr);
}
+ seqan::read(ref_stream, *ref_str, Fasta());
+ if (seqan::length(*ref_str)>0)
+ fprintf(stderr, " done (%ld bases).\n", seqan::length(*ref_str));
+ rt.get_id(name, keep_seqs ? ref_str : NULL, 0);
+ if (!keep_seqs) delete ref_str;
+ } //while FASTA records
}
RefSeg seg_from_bowtie_hit(const BowtieHit& T)
@@ -746,10 +747,10 @@ struct IntronMotifs
Dna5String seg_str = seqan::infixWithLength(ref_str,
pos - half_splice_mer_len - 1,
half_splice_mer_len + 1);
- stringstream ss(stringstream::in | stringstream::out);
- string s;
- ss << seg_str;
- ss >> s;
+ stringstream ss;
+ ss << seg_str;
+ const std::string& s = ss.str();
+ //const char* cstr=s.c_str();
string col_seg_str = convert_bp_to_color(s, true);
uint64_t idx = colorstr_to_idx(col_seg_str);
@@ -760,21 +761,24 @@ struct IntronMotifs
dinucs[i].second.last_in_string = s[half_splice_mer_len];
}
else
- {
+ { //regular sequence
if (pos <= (size_t)half_splice_mer_len || pos >= length(ref_str))
continue;
-
Dna5String seg_str = seqan::infixWithLength(ref_str,
pos - half_splice_mer_len,
half_splice_mer_len);
- stringstream ss(stringstream::in | stringstream::out);
- string s;
- ss << seg_str;
- ss >> s;
+ stringstream ss;
+ ss << seg_str;
+ const std::string& s = ss.str();
+ //const char* cstr=s.c_str();
+ //fprintf(stderr, "XXXXXXXX> infix at pos %ld (-%d) : \"%s\"\n", pos, half_splice_mer_len, cstr);
+
uint64_t idx = dna5str_to_idx(s);
dinucs[i].second.fwd_string = idx;
dinucs[i].second.rev_string = rc_dna_str(idx);
+ //fprintf(stderr, "############ attach_upstream_mers pos=%ld, seg_str=\"%s\", fwd_string=%016lX, rev_string=%016lX\n",
+ // pos, cstr, dinucs[i].second.fwd_string, dinucs[i].second.rev_string);
}
}
}
@@ -797,10 +801,10 @@ struct IntronMotifs
Dna5String seg_str = seqan::infixWithLength(ref_str,
pos + 2 - 1,
half_splice_mer_len + 1);
- stringstream ss(stringstream::in | stringstream::out);
- string s;
- ss << seg_str;
- ss >> s;
+ stringstream ss;
+ ss << seg_str;
+ const std::string& s = ss.str();
+ //const char* cstr=s.c_str();
string col_seg_str = convert_bp_to_color(s, true);
uint64_t idx = colorstr_to_idx(col_seg_str);
@@ -816,10 +820,10 @@ struct IntronMotifs
pos + 2,
half_splice_mer_len);
- stringstream ss(stringstream::in | stringstream::out);
- string s;
- ss << seg_str;
- ss >> s;
+ stringstream ss;
+ ss << seg_str;
+ const std::string& s = ss.str();
+ //const char* cstr=s.c_str();
uint64_t idx = dna5str_to_idx(s);
dinucs[i].second.fwd_string = idx;
@@ -1519,11 +1523,13 @@ bool extendable_junction(uint64_t upstream_dna_str,
size_t min_ext_len,
bool reverse,
char last_in_upstream = 'N',
- char first_in_downstream = 'N')
+ char first_in_downstream = 'N', bool locdebug=false)
{
if (color)
{
- string two_bp; two_bp.push_back(last_in_upstream); two_bp.push_back(first_in_downstream);
+ string two_bp;
+ two_bp.push_back(last_in_upstream);
+ two_bp.push_back(first_in_downstream);
string color = convert_bp_to_color(two_bp, true);
char num = (color[0] - '0') & 0x3;
@@ -1542,7 +1548,11 @@ bool extendable_junction(uint64_t upstream_dna_str,
uint32_t key = junction_key(upstream_dna_str,
downstream_dna_str,
splice_mer_len);
-
+ /*if (locdebug) {
+ fprintf(stderr, "===============x0x0x0x0x0x0x0x0x0x0x0x=== splice_mer_len=%d\n",splice_mer_len);
+ fprintf(stderr, "\t upstream_dna_str:%016lX, downstream_dna_str:%016lX\n", upstream_dna_str, downstream_dna_str);
+ fprintf(stderr, "\t junction_key:%08X\n", key);
+ }*/
upstream_dna_str >>= splice_mer_len;
downstream_dna_str <<= splice_mer_len;
@@ -1581,7 +1591,9 @@ struct RecordExtendableJuncs
size_t left_pos = left_sites[L].first;
size_t max_right_pos = left_pos + max_intron;
- for (size_t R = curr_R;
+ //fprintf(stderr, "XXXXXXXXXXX> curr_R=%ld, max_right_pos=%ld, right_sites.size()=%ld\n",
+ // curr_R, max_right_pos, right_sites.size());
+ for (size_t R = curr_R;
R < right_sites.size() && right_sites[R].first < max_right_pos; ++R)
{
uint64_t upstream_dna_str = left_sites[L].second.fwd_string;
@@ -1590,20 +1602,22 @@ struct RecordExtendableJuncs
char first_in_downstream = right_sites[R].second.first_in_string;
uint64_t rc_upstream_dna_str = left_sites[L].second.rev_string;
uint64_t rc_downstream_dna_str = right_sites[R].second.rev_string;
-
+ bool locdebug=(curr_R==28 && L==5 && R==28);
if (extendable_junction(upstream_dna_str,
downstream_dna_str, splice_mer_len, 7, false,
- last_in_upstream, first_in_downstream) ||
+ last_in_upstream, first_in_downstream, locdebug) ||
extendable_junction(rc_downstream_dna_str,
rc_upstream_dna_str, splice_mer_len, 7, true,
- last_in_upstream, first_in_downstream))
- {
+ last_in_upstream, first_in_downstream, locdebug))
+ {
+ //DEBUG:
+ //fprintf(stderr, "xxxxxxxxxx> keeping junction (L,R)=(%ld, %ld), curr_R=%ld\n", L,R,curr_R);
juncs.insert(Junction(ref_id,
left_sites[L].first - 1,
right_sites[R].first + 2,
antisense,
R - curr_R));
- }
+ }
if (juncs.size() > max_juncs)
juncs.erase(*(juncs.rbegin()));
}
@@ -2051,11 +2065,32 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
MotifMap ims;
- seqan::DnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
- seqan::DnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
+ //seqan::DnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
+ //seqan::DnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
- if (talkative)
- fprintf(stderr, "Collecting potential splice sites in islands\n");
+ seqan::DnaString rev_donor_dinuc(donor_dinuc);
+ seqan::DnaString rev_acceptor_dinuc(acceptor_dinuc);
+ seqan::reverseComplement(rev_donor_dinuc);
+ seqan::reverseComplement(rev_acceptor_dinuc);
+
+ /* typedef seqan::ModifiedString<
+ seqan::ModifiedString<seqan::DnaString const, seqan::ModView<seqan::FunctorComplement<seqan::Dna> > >,
+ seqan::ModReverse> ConstDnaStringReverseComplement;
+ ConstDnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
+ ConstDnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
+ */
+
+ if (talkative) {
+ stringstream sdon,sacc;
+ sdon << donor_dinuc;
+ sacc << acceptor_dinuc;
+ const std::string& acctmp = sacc.str();
+ const char* accstr = acctmp.c_str();
+ const std::string& dontmp = sdon.str();
+ const char* donstr = dontmp.c_str();
+ fprintf(stderr, "Collecting potential splice sites in islands (%s-%s)\n",
+ donstr, accstr);
+ }
//
bool all_both = true;
@@ -2306,7 +2341,8 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
//motifs.attach_mer_counts(*ref_str);
motifs.attach_mers(*ref_str);
-
+ //DEBUG: fprintf(stderr, "\tFWD (donors, acceptors) = (%d, %d)\n\tREV (donors, acceptors) = (%d, %d)\n",
+ // motifs.fwd_donors.size(), motifs.fwd_acceptors.size(), motifs.rev_donors.size(), motifs.rev_acceptors.size());
vector<pair<size_t, DnaSpliceStrings> >& fwd_donors = motifs.fwd_donors;
vector<pair<size_t, DnaSpliceStrings> >& fwd_acceptors = motifs.fwd_acceptors;
vector<pair<size_t, DnaSpliceStrings> >& rev_acceptors = motifs.rev_acceptors;
@@ -2324,7 +2360,8 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
max_intron,
max_juncs,
half_splice_mer_len);
-
+ //DEBUG:
+ // fprintf(stderr, "\tFWD potential juncs: %d\n", juncs.size());
recorder.record(ref_id,
rev_acceptors,
rev_donors,
@@ -2334,6 +2371,7 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
max_intron,
max_juncs,
half_splice_mer_len);
+ //DEBUG: fprintf(stderr, "\ttotal FWD+REV potential juncs: %d\n", juncs.size());
}
//fprintf(stderr, "Found %d total splices\n", num_juncs);
}
@@ -3577,7 +3615,6 @@ void find_gaps(RefSequenceTable& rt,
}
}
} //for each hits_for_read
-
juncs_from_ref_segs<RecordSegmentJuncs>(rt,
expected_don_acc_windows,
seg_juncs,
@@ -4491,6 +4528,7 @@ void capture_island_ends(ReadTable& it,
expected_look_left_windows.end());
if (!butterfly_search) coverage_map.clear(); //free some memory
+ //fprintf(stderr, "--------->>>>>> RecordExtendableJuncs <<<<<<---------\n");
juncs_from_ref_segs<RecordExtendableJuncs>(rt,
expected_don_acc_windows,
cov_juncs,
@@ -4501,7 +4539,7 @@ void capture_island_ends(ReadTable& it,
max_cov_juncs,
true,
half_splice_mer_len);
- //fprintf(stderr, "Found %ld potential island-end pairing junctions\n", (long int)cov_juncs.size());
+ //fprintf(stderr, "############# found %ld potential island-end pairing junctions\n", (long int)cov_juncs.size());
}
void print_juncs(RefSequenceTable& rt, std::set<Junction, skip_count_lt>& juncs, const char* str)
@@ -4713,7 +4751,7 @@ void driver(istream& ref_stream,
if (left_segmap_fnames.size() > 1)
{
- fprintf( stderr, "Loading left segment hits...\n");
+ fprintf( stderr, "Loading left segment hits... ");fflush(stderr);
vector<uint64_t> read_ids;
vector<vector<int64_t> > offsets;
@@ -4792,7 +4830,7 @@ void driver(istream& ref_stream,
if (right_segmap_fnames.size() > 1)
{
- fprintf( stderr, "Loading right segment hits...\n");
+ fprintf( stderr, "Loading right segment hits...");fflush(stderr);
vector<uint64_t> read_ids;
vector<vector<int64_t> > offsets;
diff --git a/src/sortedcontainers/__init__.py b/src/sortedcontainers/__init__.py
new file mode 100755
index 0000000..98e04cd
--- /dev/null
+++ b/src/sortedcontainers/__init__.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+"""
+sortedcontainers Sorted Container Types Library
+===============================================
+
+SortedContainers is an Apache2 licensed containers library, written in
+pure-Python, and fast as C-extensions.
+
+Python's standard library is great until you need a sorted container type. Many
+will attest that you can get really far without one, but the moment you
+**really need** a sorted list, dict, or set, you're faced with a dozen
+different implementations, most using C-extensions without great documentation
+and benchmarking.
+
+Things shouldn't be this way. Not in Python.
+
+::
+
+ >>> from sortedcontainers import SortedList, SortedDict, SortedSet
+ >>> sl = SortedList(xrange(10000000))
+ >>> 1234567 in sl
+ True
+ >>> sl[7654321]
+ 7654321
+ >>> sl.add(1234567)
+ >>> sl.count(1234567)
+ 2
+ >>> sl *= 3
+ >>> len(sl)
+ 30000003
+
+SortedContainers takes all of the work out of Python sorted types - making your
+deployment and use of Python easy. There's no need to install a C compiler or
+pre-build and distribute custom extensions. Performance is a feature and
+testing has 100% coverage with unit tests and hours of stress.
+
+:copyright: (c) 2014 by Grant Jenks.
+:license: Apache 2.0, see LICENSE for more details.
+
+"""
+
+__title__ = 'sortedcontainers'
+__version__ = '0.9.4'
+__build__ = 0x000904
+__author__ = 'Grant Jenks'
+__license__ = 'Apache 2.0'
+__copyright__ = 'Copyright 2014 Grant Jenks'
+
+from .sortedlist import SortedList
+from .sortedset import SortedSet
+from .sorteddict import SortedDict
+from .sortedlistwithkey import SortedListWithKey
+
+__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey']
diff --git a/src/sortedcontainers/sorteddict.py b/src/sortedcontainers/sorteddict.py
new file mode 100755
index 0000000..0282ad5
--- /dev/null
+++ b/src/sortedcontainers/sorteddict.py
@@ -0,0 +1,737 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted dict implementation.
+
+from .sortedset import SortedSet
+from .sortedlist import SortedList, recursive_repr
+from .sortedlistwithkey import SortedListWithKey
+from collections import Set, Sequence
+from collections import KeysView as AbstractKeysView
+from collections import ValuesView as AbstractValuesView
+from collections import ItemsView as AbstractItemsView
+
+from functools import wraps
+from sys import hexversion
+
+_NotGiven = object()
+
+def not26(func):
+ """Function decorator for methods not implemented in Python 2.6."""
+
+ @wraps(func)
+ def errfunc(*args, **kwargs):
+ raise NotImplementedError
+
+ if hexversion < 0x02070000:
+ return errfunc
+ else:
+ return func
+
+class _IlocWrapper:
+ def __init__(self, _dict):
+ self._dict = _dict
+ def __len__(self):
+ return len(self._dict)
+ def __getitem__(self, index):
+ """
+ Very efficiently return the key at index *index* in iteration. Supports
+ negative indices and slice notation. Raises IndexError on invalid
+ *index*.
+ """
+ return self._dict._list[index]
+ def __delitem__(self, index):
+ """
+ Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports negative
+ indices and slice notation. Raises IndexError on invalid *index*.
+ """
+ _temp = self._dict
+ _list = _temp._list
+ _delitem = _temp._delitem
+
+ if isinstance(index, slice):
+ keys = _list[index]
+ del _list[index]
+ for key in keys:
+ _delitem(key)
+ else:
+ key = _list[index]
+ del _list[index]
+ _delitem(key)
+
+class SortedDict(dict):
+ """
+ A SortedDict provides the same methods as a dict. Additionally, a
+ SortedDict efficiently maintains its keys in sorted order. Consequently, the
+ keys method will return the keys in sorted order, the popitem method will
+ remove the item with the highest key, etc.
+ """
+ def __init__(self, *args, **kwargs):
+ """
+ A SortedDict provides the same methods as a dict. Additionally, a
+ SortedDict efficiently maintains its keys in sorted order. Consequently,
+ the keys method will return the keys in sorted order, the popitem method
+ will remove the item with the highest key, etc.
+
+ An optional *key* argument defines a callable that, like the `key`
+ argument to Python's `sorted` function, extracts a comparison key from
+ each dict key. If no function is specified, the default compares the
+ dict keys directly. The `key` argument must be provided as a positional
+ argument and must come before all other arguments.
+
+ An optional *load* argument defines the load factor of the internal list
+ used to maintain sort order. If present, this argument must come before
+ an iterable. The default load factor of '1000' works well for lists from
+ tens to tens of millions of elements. Good practice is to use a value
+ that is the cube root of the list size. With billions of elements, the
+ best load factor depends on your usage. It's best to leave the load
+ factor at the default until you start benchmarking.
+
+ An optional *iterable* argument provides an initial series of items to
+ populate the SortedDict. Each item in the series must itself contain
+ two items. The first is used as a key in the new dictionary, and the
+ second as the key's value. If a given key is seen more than once, the
+ last value associated with it is retained in the new dictionary.
+
+ If keyword arguments are given, the keywords themselves with their
+ associated values are added as items to the dictionary. If a key is
+ specified both in the positional argument and as a keyword argument, the
+ value associated with the keyword is retained in the dictionary. For
+ example, these all return a dictionary equal to ``{"one": 2, "two":
+ 3}``:
+
+ * ``SortedDict(one=2, two=3)``
+ * ``SortedDict({'one': 2, 'two': 3})``
+ * ``SortedDict(zip(('one', 'two'), (2, 3)))``
+ * ``SortedDict([['two', 3], ['one', 2]])``
+
+ The first example only works for keys that are valid Python
+ identifiers; the others work with any valid keys.
+ """
+ if len(args) > 0 and (args[0] is None or callable(args[0])):
+ self._key = args[0]
+ args = args[1:]
+ else:
+ self._key = None
+
+ if len(args) > 0 and type(args[0]) == int:
+ self._load = args[0]
+ args = args[1:]
+ else:
+ self._load = 1000
+
+ if self._key is None:
+ self._list = SortedList(load=self._load)
+ else:
+ self._list = SortedListWithKey(key=self._key, load=self._load)
+
+ # Cache function pointers to dict methods.
+
+ _dict = super(SortedDict, self)
+ self._dict = _dict
+ self._clear = _dict.clear
+ self._delitem = _dict.__delitem__
+ self._iter = _dict.__iter__
+ self._pop = _dict.pop
+ self._setdefault = _dict.setdefault
+ self._setitem = _dict.__setitem__
+ self._update = _dict.update
+
+ # Cache function pointers to SortedList methods.
+
+ self._list_add = self._list.add
+ self._list_bisect_left = self._list.bisect_left
+ self._list_bisect_right = self._list.bisect_right
+ self._list_clear = self._list.clear
+ self._list_index = self._list.index
+ self._list_pop = self._list.pop
+ self._list_remove = self._list.remove
+ self._list_update = self._list.update
+
+ self.iloc = _IlocWrapper(self)
+
+ self.update(*args, **kwargs)
+
+ def clear(self):
+ """Remove all elements from the dictionary."""
+ self._clear()
+ self._list_clear()
+
+ def __delitem__(self, key):
+ """
+ Remove ``d[key]`` from *d*. Raises a KeyError if *key* is not in the
+ dictionary.
+ """
+ self._delitem(key)
+ self._list_remove(key)
+
+ def __iter__(self):
+ """Create an iterator over the sorted keys of the dictionary."""
+ return iter(self._list)
+
+ def __reversed__(self):
+ """
+ Create a reversed iterator over the sorted keys of the dictionary.
+ """
+ return reversed(self._list)
+
+ def __setitem__(self, key, value):
+ """Set `d[key]` to *value*."""
+ if key not in self:
+ self._list_add(key)
+ self._setitem(key, value)
+
+ def copy(self):
+ """Return a shallow copy of the sorted dictionary."""
+ return self.__class__(self._key, self._load, self.iteritems())
+
+ __copy__ = copy
+
+ @classmethod
+ def fromkeys(cls, seq, value=None):
+ """
+ Create a new dictionary with keys from *seq* and values set to *value*.
+ """
+ return cls((key, value) for key in seq)
+
+ if hexversion < 0x03000000:
+ def items(self):
+ """
+ Return a list of the dictionary's items (``(key, value)`` pairs).
+ """
+ return list(self.iteritems())
+ else:
+ def items(self):
+ """
+ Return a new ItemsView of the dictionary's items. In addition to
+ the methods provided by the built-in `view` the ItemsView is
+ indexable (e.g. ``d.items()[5]``).
+ """
+ return ItemsView(self)
+
+ def iteritems(self):
+ """Return an iterable over the items (``(key, value)`` pairs)."""
+ return iter((key, self[key]) for key in self._list)
+
+ if hexversion < 0x03000000:
+ def keys(self):
+ """Return a SortedSet of the dictionary's keys."""
+ return SortedSet(self._list, key=self._key, load=self._load)
+ else:
+ def keys(self):
+ """
+ Return a new KeysView of the dictionary's keys. In addition to the
+ methods provided by the built-in `view` the KeysView is indexable
+ (e.g. ``d.keys()[5]``).
+ """
+ return KeysView(self)
+
+ def iterkeys(self):
+ """Return an iterable over the keys of the dictionary."""
+ return iter(self._list)
+
+ if hexversion < 0x03000000:
+ def values(self):
+ """Return a list of the dictionary's values."""
+ return list(self.itervalues())
+ else:
+ def values(self):
+ """
+ Return a new :class:`ValuesView` of the dictionary's values.
+ In addition to the methods provided by the built-in `view` the
+ ValuesView is indexable (e.g., ``d.values()[5]``).
+ """
+ return ValuesView(self)
+
+ def itervalues(self):
+ """Return an iterable over the values of the dictionary."""
+ return iter(self[key] for key in self._list)
+
+ def pop(self, key, default=_NotGiven):
+ """
+ If *key* is in the dictionary, remove it and return its value,
+ else return *default*. If *default* is not given and *key* is not in
+ the dictionary, a KeyError is raised.
+ """
+ if key in self:
+ self._list_remove(key)
+ return self._pop(key)
+ else:
+ if default is _NotGiven:
+ raise KeyError(key)
+ else:
+ return default
+
+ def popitem(self):
+ """
+ Remove and return the ``(key, value)`` pair with the greatest *key*
+ from the dictionary.
+
+ If the dictionary is empty, calling `popitem` raises a
+ KeyError`.
+ """
+ if not len(self):
+ raise KeyError('popitem(): dictionary is empty')
+
+ key = self._list_pop()
+ value = self._pop(key)
+
+ return (key, value)
+
+ def setdefault(self, key, default=None):
+ """
+ If *key* is in the dictionary, return its value. If not, insert *key*
+ with a value of *default* and return *default*. *default* defaults to
+ ``None``.
+ """
+ if key in self:
+ return self[key]
+ else:
+ self._setitem(key, default)
+ self._list_add(key)
+ return default
+
+ def update(self, *args, **kwargs):
+ """
+ Update the dictionary with the key/value pairs from *other*, overwriting
+ existing keys.
+
+ *update* accepts either another dictionary object or an iterable of
+ key/value pairs (as a tuple or other iterable of length two). If
+ keyword arguments are specified, the dictionary is then updated with
+ those key/value pairs: ``d.update(red=1, blue=2)``.
+ """
+ if not len(self):
+ self._update(*args, **kwargs)
+ self._list_update(self._iter())
+ return
+
+ if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
+ pairs = args[0]
+ else:
+ pairs = dict(*args, **kwargs)
+
+ if (10 * len(pairs)) > len(self):
+ self._update(pairs)
+ self._list_clear()
+ self._list_update(self._iter())
+ else:
+ for key in pairs:
+ self[key] = pairs[key]
+
+ def index(self, key, start=None, stop=None):
+ """
+ Return the smallest *k* such that `d.iloc[k] == key` and `i <= k < j`.
+ Raises `ValueError` if *key* is not present. *stop* defaults to the end
+ of the set. *start* defaults to the beginning. Negative indexes are
+ supported, as for slice indices.
+ """
+ return self._list_index(key, start, stop)
+
+ def bisect_left(self, key):
+ """
+ Similar to the ``bisect`` module in the standard library, this returns
+ an appropriate index to insert *key* in SortedDict. If *key* is
+ already present in SortedDict, the insertion point will be before (to
+ the left of) any existing entries.
+ """
+ return self._list_bisect_left(key)
+
+ def bisect(self, key):
+ """Same as bisect_right."""
+ return self._list_bisect_right(key)
+
+ def bisect_right(self, key):
+ """
+ Same as `bisect_left`, but if *key* is already present in SortedDict,
+ the insertion point will be after (to the right of) any existing
+ entries.
+ """
+ return self._list_bisect_right(key)
+
+ @not26
+ def viewkeys(self):
+ """
+ In Python 2.7 and later, return a new `KeysView` of the dictionary's
+ keys.
+
+ In Python 2.6, raise a NotImplementedError.
+ """
+ return KeysView(self)
+
+ @not26
+ def viewvalues(self):
+ """
+ In Python 2.7 and later, return a new `ValuesView` of the dictionary's
+ values.
+
+ In Python 2.6, raise a NotImplementedError.
+ """
+ return ValuesView(self)
+
+ @not26
+ def viewitems(self):
+ """
+ In Python 2.7 and later, return a new `ItemsView` of the dictionary's
+ items.
+
+ In Python 2.6, raise a NotImplementedError.
+ """
+ return ItemsView(self)
+
+ def __reduce__(self):
+ return (self.__class__, (self._key, self._load, list(self.iteritems())))
+
+ @recursive_repr
+ def __repr__(self):
+ temp = '{0}({1}, {2}, {{{3}}})'
+ items = ', '.join('{0}: {1}'.format(repr(key), repr(self[key]))
+ for key in self._list)
+ return temp.format(
+ self.__class__.__name__,
+ repr(self._key),
+ repr(self._load),
+ items
+ )
+
+ def _check(self):
+ self._list._check()
+ assert len(self) == len(self._list)
+ assert all(val in self for val in self._list)
+
+class KeysView(AbstractKeysView, Set, Sequence):
+ """
+ A KeysView object is a dynamic view of the dictionary's keys, which
+ means that when the dictionary's keys change, the view reflects
+ those changes.
+
+ The KeysView class implements the Set and Sequence Abstract Base Classes.
+ """
+ if hexversion < 0x03000000:
+ def __init__(self, sorted_dict):
+ """
+ Initialize a KeysView from a SortedDict container as *sorted_dict*.
+ """
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.viewkeys()
+ else:
+ def __init__(self, sorted_dict):
+ """
+ Initialize a KeysView from a SortedDict container as *sorted_dict*.
+ """
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.keys()
+ def __len__(self):
+ """Return the number of entries in the dictionary."""
+ return len(self._view)
+ def __contains__(self, key):
+ """
+ Return True if and only if *key* is one of the underlying dictionary's
+ keys.
+ """
+ return key in self._view
+ def __iter__(self):
+ """
+ Return an iterable over the keys in the dictionary. Keys are iterated
+ over in their sorted order.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a RuntimeError or fail to iterate over all entries.
+ """
+ return iter(self._list)
+ def __getitem__(self, index):
+ """Return the key at position *index*."""
+ return self._list[index]
+ def __reversed__(self):
+ """
+ Return a reversed iterable over the keys in the dictionary. Keys are
+ iterated over in their reverse sort order.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a RuntimeError or fail to iterate over all entries.
+ """
+ return reversed(self._list)
+ def index(self, value, start=None, stop=None):
+ """
+ Return the smallest *k* such that `keysview[k] == value` and `start <= k
+ < end`. Raises `KeyError` if *value* is not present. *stop* defaults
+ to the end of the set. *start* defaults to the beginning. Negative
+ indexes are supported, as for slice indices.
+ """
+ return self._list.index(value, start, stop)
+ def count(self, value):
+ """Return the number of occurrences of *value* in the set."""
+ return 1 if value in self._view else 0
+ def __eq__(self, that):
+ """Test set-like equality with *that*."""
+ return self._view == that
+ def __ne__(self, that):
+ """Test set-like inequality with *that*."""
+ return self._view != that
+ def __lt__(self, that):
+ """Test whether self is a proper subset of *that*."""
+ return self._view < that
+ def __gt__(self, that):
+ """Test whether self is a proper superset of *that*."""
+ return self._view > that
+ def __le__(self, that):
+ """Test whether self is contained within *that*."""
+ return self._view <= that
+ def __ge__(self, that):
+ """Test whether *that* is contained within self."""
+ return self._view >= that
+ def __and__(self, that):
+ """Return a SortedSet of the intersection of self and *that*."""
+ return SortedSet(self._view & that)
+ def __or__(self, that):
+ """Return a SortedSet of the union of self and *that*."""
+ return SortedSet(self._view | that)
+ def __sub__(self, that):
+ """Return a SortedSet of the difference of self and *that*."""
+ return SortedSet(self._view - that)
+ def __xor__(self, that):
+ """Return a SortedSet of the symmetric difference of self and *that*."""
+ return SortedSet(self._view ^ that)
+ if hexversion < 0x03000000:
+ def isdisjoint(self, that):
+ """Return True if and only if *that* is disjoint with self."""
+ return not any(key in self._list for key in that)
+ else:
+ def isdisjoint(self, that):
+ """Return True if and only if *that* is disjoint with self."""
+ return self._view.isdisjoint(that)
+ @recursive_repr
+ def __repr__(self):
+ return 'SortedDict_keys({0})'.format(repr(list(self)))
+
+class ValuesView(AbstractValuesView, Sequence):
+ """
+ A ValuesView object is a dynamic view of the dictionary's values, which
+ means that when the dictionary's values change, the view reflects those
+ changes.
+
+ The ValuesView class implements the Sequence Abstract Base Class.
+ """
+ if hexversion < 0x03000000:
+ def __init__(self, sorted_dict):
+ """
+ Initialize a ValuesView from a SortedDict container as
+ *sorted_dict*.
+ """
+ self._dict = sorted_dict
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.viewvalues()
+ else:
+ def __init__(self, sorted_dict):
+ """
+ Initialize a ValuesView from a SortedDict container as
+ *sorted_dict*.
+ """
+ self._dict = sorted_dict
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.values()
+ def __len__(self):
+ """Return the number of entries in the dictionary."""
+ return len(self._dict)
+ def __contains__(self, value):
+ """
+ Return True if and only if *value* is on the underlying dictionary's
+ values.
+ """
+ return value in self._view
+ def __iter__(self):
+ """
+ Return an iterator over the values in the dictionary. Values are
+ iterated over in sorted order of the keys.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a `RuntimeError` or fail to iterate over all entries.
+ """
+ _dict = self._dict
+ return iter(_dict[key] for key in self._list)
+ def __getitem__(self, index):
+ """
+ Efficiently return value at *index* in iteration.
+
+ Supports slice notation and negative indexes.
+ """
+ _dict, _list = self._dict, self._list
+ if isinstance(index, slice):
+ return [_dict[key] for key in _list[index]]
+ else:
+ return _dict[_list[index]]
+ def __reversed__(self):
+ """
+ Return a reverse iterator over the values in the dictionary. Values are
+ iterated over in reverse sort order of the keys.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a `RuntimeError` or fail to iterate over all entries.
+ """
+ _dict = self._dict
+ return iter(_dict[key] for key in reversed(self._list))
+ def index(self, value):
+ """
+ Return index of *value* in self.
+
+ Raises ValueError if *value* is not found.
+ """
+ for idx, val in enumerate(self):
+ if value == val:
+ return idx
+ else:
+ raise ValueError('{0} is not in dict'.format(repr(value)))
+ if hexversion < 0x03000000:
+ def count(self, value):
+ """Return the number of occurrences of *value* in self."""
+ return sum(1 for val in self._dict.itervalues() if val == value)
+ else:
+ def count(self, value):
+ """Return the number of occurrences of *value* in self."""
+ return sum(1 for val in _dict.values() if val == value)
+ def __lt__(self, that):
+ raise TypeError
+ def __gt__(self, that):
+ raise TypeError
+ def __le__(self, that):
+ raise TypeError
+ def __ge__(self, that):
+ raise TypeError
+ def __and__(self, that):
+ raise TypeError
+ def __or__(self, that):
+ raise TypeError
+ def __sub__(self, that):
+ raise TypeError
+ def __xor__(self, that):
+ raise TypeError
+ @recursive_repr
+ def __repr__(self):
+ return 'SortedDict_values({0})'.format(repr(list(self)))
+
+class ItemsView(AbstractItemsView, Set, Sequence):
+ """
+ An ItemsView object is a dynamic view of the dictionary's ``(key,
+ value)`` pairs, which means that when the dictionary changes, the
+ view reflects those changes.
+
+ The ItemsView class implements the Set and Sequence Abstract Base Classes.
+ However, the set-like operations (``&``, ``|``, ``-``, ``^``) will only
+ operate correctly if all of the dictionary's values are hashable.
+ """
+ if hexversion < 0x03000000:
+ def __init__(self, sorted_dict):
+ """
+ Initialize an ItemsView from a SortedDict container as
+ *sorted_dict*.
+ """
+ self._dict = sorted_dict
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.viewitems()
+ else:
+ def __init__(self, sorted_dict):
+ """
+ Initialize an ItemsView from a SortedDict container as
+ *sorted_dict*.
+ """
+ self._dict = sorted_dict
+ self._list = sorted_dict._list
+ self._view = sorted_dict._dict.items()
+ def __len__(self):
+ """Return the number of entries in the dictionary."""
+ return len(self._view)
+ def __contains__(self, key):
+ """
+ Return True if and only if *key* is one of the underlying dictionary's
+ items.
+ """
+ return key in self._view
+ def __iter__(self):
+ """
+ Return an iterable over the items in the dictionary. Items are iterated
+ over in their sorted order.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a RuntimeError or fail to iterate over all entries.
+ """
+ _dict = self._dict
+ return iter((key, _dict[key]) for key in self._list)
+ def __getitem__(self, index):
+ """Return the item as position *index*."""
+ _dict, _list = self._dict, self._list
+ if isinstance(index, slice):
+ return [(key, _dict[key]) for key in _list[index]]
+ else:
+ key = _list[index]
+ return (key, _dict[key])
+ def __reversed__(self):
+ """
+ Return a reversed iterable over the items in the dictionary. Items are
+ iterated over in their reverse sort order.
+
+ Iterating views while adding or deleting entries in the dictionary may
+ raise a RuntimeError or fail to iterate over all entries.
+ """
+ _dict = self._dict
+ return iter((key, _dict[key]) for key in reversed(self._list))
+ def index(self, key, start=None, stop=None):
+ """
+ Return the smallest *k* such that `itemssview[k] == key` and `start <= k
+ < end`. Raises `KeyError` if *key* is not present. *stop* defaults
+ to the end of the set. *start* defaults to the beginning. Negative
+ indexes are supported, as for slice indices.
+ """
+ temp, value = key
+ pos = self._list.index(temp, start, stop)
+ if value == self._dict[temp]:
+ return pos
+ else:
+ raise ValueError('{0} is not in dict'.format(repr(key)))
+ def count(self, item):
+ """Return the number of occurrences of *item* in the set."""
+ key, value = item
+ return 1 if key in self._dict and self._dict[key] == value else 0
+ def __eq__(self, that):
+ """Test set-like equality with *that*."""
+ return self._view == that
+ def __ne__(self, that):
+ """Test set-like inequality with *that*."""
+ return self._view != that
+ def __lt__(self, that):
+ """Test whether self is a proper subset of *that*."""
+ return self._view < that
+ def __gt__(self, that):
+ """Test whether self is a proper superset of *that*."""
+ return self._view > that
+ def __le__(self, that):
+ """Test whether self is contained within *that*."""
+ return self._view <= that
+ def __ge__(self, that):
+ """Test whether *that* is contained within self."""
+ return self._view >= that
+ def __and__(self, that):
+ """Return a SortedSet of the intersection of self and *that*."""
+ return SortedSet(self._view & that)
+ def __or__(self, that):
+ """Return a SortedSet of the union of self and *that*."""
+ return SortedSet(self._view | that)
+ def __sub__(self, that):
+ """Return a SortedSet of the difference of self and *that*."""
+ return SortedSet(self._view - that)
+ def __xor__(self, that):
+ """Return a SortedSet of the symmetric difference of self and *that*."""
+ return SortedSet(self._view ^ that)
+ if hexversion < 0x03000000:
+ def isdisjoint(self, that):
+ """Return True if and only if *that* is disjoint with self."""
+ _dict = self._dict
+ for key, value in that:
+ if key in _dict and _dict[key] == value:
+ return False
+ return True
+ else:
+ def isdisjoint(self, that):
+ """Return True if and only if *that* is disjoint with self."""
+ return self._view.isdisjoint(that)
+ @recursive_repr
+ def __repr__(self):
+ return 'SortedDict_items({0})'.format(repr(list(self)))
diff --git a/src/sortedcontainers/sortedlist.py b/src/sortedcontainers/sortedlist.py
new file mode 100755
index 0000000..8549cb4
--- /dev/null
+++ b/src/sortedcontainers/sortedlist.py
@@ -0,0 +1,1233 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted list implementation.
+
+from __future__ import print_function
+from sys import hexversion
+
+from bisect import bisect_left, bisect_right, insort
+from itertools import chain, repeat, starmap
+from collections import MutableSequence
+from operator import iadd, add
+from functools import wraps
+from math import log
+
+if hexversion < 0x03000000:
+ from itertools import izip as zip
+ from itertools import imap as map
+ try:
+ from thread import get_ident
+ except ImportError:
+ from dummy_thread import get_ident
+else:
+ from functools import reduce
+ try:
+ from _thread import get_ident
+ except ImportError:
+ from _dummy_thread import get_ident
+
+def recursive_repr(func):
+ """Decorator to prevent infinite repr recursion."""
+ repr_running = set()
+
+ @wraps(func)
+ def wrapper(self):
+ key = id(self), get_ident()
+
+ if key in repr_running:
+ return '...'
+
+ repr_running.add(key)
+
+ try:
+ return func(self)
+ finally:
+ repr_running.discard(key)
+
+ return wrapper
+
+class SortedList(MutableSequence):
+ """
+ SortedList provides most of the same methods as a list but keeps the items
+ in sorted order.
+ """
+
+ def __init__(self, iterable=None, load=1000):
+ """
+ SortedList provides most of the same methods as a list but keeps the
+ items in sorted order.
+
+ An optional *iterable* provides an initial series of items to populate
+ the SortedList.
+
+ An optional *load* specifies the load-factor of the list. The default
+ load factor of '1000' works well for lists from tens to tens of millions
+ of elements. Good practice is to use a value that is the cube root of
+ the list size. With billions of elements, the best load factor depends
+ on your usage. It's best to leave the load factor at the default until
+ you start benchmarking.
+ """
+ self._len, self._maxes, self._lists, self._index = 0, [], [], []
+ self._load, self._twice, self._half = load, load * 2, load >> 1
+ self._offset = 0
+
+ if iterable is not None:
+ self.update(iterable)
+
+ def clear(self):
+ """Remove all the elements from the list."""
+ self._len = 0
+ del self._maxes[:]
+ del self._lists[:]
+ del self._index[:]
+
+ def add(self, val):
+ """Add the element *val* to the list."""
+ _maxes, _lists = self._maxes, self._lists
+
+ if _maxes:
+ pos = bisect_right(_maxes, val)
+
+ if pos == len(_maxes):
+ pos -= 1
+ _maxes[pos] = val
+ _lists[pos].append(val)
+ else:
+ insort(_lists[pos], val)
+
+ self._expand(pos)
+ else:
+ _maxes.append(val)
+ _lists.append([val])
+
+ self._len += 1
+
+ def _expand(self, pos):
+ """Splits sublists that are more than double the load level.
+
+ Updates the index when the sublist length is less than double the load
+ level. This requires incrementing the nodes in a traversal from the leaf
+ node to the root. For an example traversal see self._loc.
+ """
+ _lists, _index = self._lists, self._index
+
+ if len(_lists[pos]) > self._twice:
+ _maxes, _load = self._maxes, self._load
+ half = _lists[pos][_load:]
+ del _lists[pos][_load:]
+ _maxes[pos] = _lists[pos][-1]
+ _maxes.insert(pos + 1, half[-1])
+ _lists.insert(pos + 1, half)
+ del _index[:]
+ else:
+ if len(_index) > 0:
+ child = self._offset + pos
+ while child > 0:
+ _index[child] += 1
+ child = (child - 1) >> 1
+ _index[0] += 1
+
+ def update(self, iterable):
+ """Update the list by adding all elements from *iterable*."""
+ _maxes, _lists = self._maxes, self._lists
+ values = sorted(iterable)
+
+ if _maxes:
+ if len(values) * 4 >= self._len:
+ values.extend(chain.from_iterable(_lists))
+ values.sort()
+ self.clear()
+ else:
+ _add = self.add
+ for val in values:
+ _add(val)
+ return
+
+ _load, _index = self._load, self._index
+ _lists.extend(values[pos:(pos + _load)]
+ for pos in range(0, len(values), _load))
+ _maxes.extend(sublist[-1] for sublist in _lists)
+ self._len = len(values)
+ del _index[:]
+
+ def __contains__(self, val):
+ """Return True if and only if *val* is an element in the list."""
+ _maxes = self._maxes
+
+ if not _maxes:
+ return False
+
+ pos = bisect_left(_maxes, val)
+
+ if pos == len(_maxes):
+ return False
+
+ _lists = self._lists
+ idx = bisect_left(_lists[pos], val)
+ return _lists[pos][idx] == val
+
+ def discard(self, val):
+ """
+ Remove the first occurrence of *val*.
+
+ If *val* is not a member, does nothing.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return
+
+ pos = bisect_left(_maxes, val)
+
+ if pos == len(_maxes):
+ return
+
+ _lists = self._lists
+ idx = bisect_left(_lists[pos], val)
+ if _lists[pos][idx] == val:
+ self._delete(pos, idx)
+
+ def remove(self, val):
+ """
+ Remove first occurrence of *val*.
+
+ Raises ValueError if *val* is not present.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ raise ValueError('{0} not in list'.format(repr(val)))
+
+ pos = bisect_left(_maxes, val)
+
+ if pos == len(_maxes):
+ raise ValueError('{0} not in list'.format(repr(val)))
+
+ _lists = self._lists
+ idx = bisect_left(_lists[pos], val)
+ if _lists[pos][idx] == val:
+ self._delete(pos, idx)
+ else:
+ raise ValueError('{0} not in list'.format(repr(val)))
+
+ def _delete(self, pos, idx):
+ """Delete the item at the given (pos, idx).
+
+ Combines lists that are less than half the load level.
+
+ Updates the index when the sublist length is more than half the load
+ level. This requires decrementing the nodes in a traversal from the leaf
+ node to the root. For an example traversal see self._loc.
+ """
+ _maxes, _lists, _index = self._maxes, self._lists, self._index
+
+ lists_pos = _lists[pos]
+
+ del lists_pos[idx]
+ self._len -= 1
+
+ len_lists_pos = len(lists_pos)
+
+ if len_lists_pos > self._half:
+
+ _maxes[pos] = lists_pos[-1]
+
+ if len(_index) > 0:
+ child = self._offset + pos
+ while child > 0:
+ _index[child] -= 1
+ child = (child - 1) >> 1
+ _index[0] -= 1
+
+ elif len(_lists) > 1:
+
+ if not pos:
+ pos += 1
+
+ prev = pos - 1
+ _lists[prev].extend(_lists[pos])
+ _maxes[prev] = _lists[prev][-1]
+
+ del _maxes[pos]
+ del _lists[pos]
+ del _index[:]
+
+ self._expand(prev)
+
+ elif len_lists_pos:
+
+ _maxes[pos] = lists_pos[-1]
+
+ else:
+
+ del _maxes[pos]
+ del _lists[pos]
+ del _index[:]
+
+ def _loc(self, pos, idx):
+ """Convert an index pair (alpha, beta) into a single index that corresponds to
+ the position of the value in the sorted list.
+
+ Most queries require the index be built. Details of the index are
+ described in self._build_index.
+
+ Indexing requires traversing the tree from a leaf node to the root. The
+ parent of each node is easily computable at (pos - 1) // 2.
+
+ Left-child nodes are always at odd indices and right-child nodes are
+ always at even indices.
+
+ When traversing up from a right-child node, increment the total by the
+ left-child node.
+
+ The final index is the sum from traversal and the index in the sublist.
+
+ For example, using the index from self._build_index:
+
+ _index = 14 5 9 3 2 4 5
+ _offset = 3
+
+ Tree:
+
+ 14
+ 5 9
+ 3 2 4 5
+
+ Converting index pair (2, 3) into a single index involves iterating like
+ so:
+
+ 1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
+ the node as a left-child node. At such nodes, we simply traverse to
+ the parent.
+
+ 2. At node 9, position 2, we recognize the node as a right-child node
+ and accumulate the left-child in our total. Total is now 5 and we
+ traverse to the parent at position 0.
+
+ 3. Iteration ends at the root.
+
+ Computing the index is the sum of the total and beta: 5 + 3 = 8.
+ """
+ if not pos:
+ return idx
+
+ _index = self._index
+
+ if not len(_index):
+ self._build_index()
+
+ total = 0
+
+ # Increment pos to point in the index to len(self._lists[pos]).
+
+ pos += self._offset
+
+ # Iterate until reaching the root of the index tree at pos = 0.
+
+ while pos:
+
+ # Right-child nodes are at odd indices. At such indices
+ # account the total below the left child node.
+
+ if not (pos & 1):
+ total += _index[pos - 1]
+
+ # Advance pos to the parent node.
+
+ pos = (pos - 1) >> 1
+
+ return total + idx
+
+ def _pos(self, idx):
+ """Convert an index into a pair (alpha, beta) that can be used to access
+ the corresponding _lists[alpha][beta] position.
+
+ Most queries require the index be built. Details of the index are
+ described in self._build_index.
+
+ Indexing requires traversing the tree to a leaf node. Each node has
+ two children which are easily computable. Given an index, pos, the
+ left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
+
+ When the index is less than the left-child, traversal moves to the
+ left sub-tree. Otherwise, the index is decremented by the left-child
+ and traversal moves to the right sub-tree.
+
+ At a child node, the indexing pair is computed from the relative
+ position of the child node as compared with the offset and the remaining
+ index.
+
+ For example, using the index from self._build_index:
+
+ _index = 14 5 9 3 2 4 5
+ _offset = 3
+
+ Tree:
+
+ 14
+ 5 9
+ 3 2 4 5
+
+ Indexing position 8 involves iterating like so:
+
+ 1. Starting at the root, position 0, 8 is compared with the left-child
+ node (5) which it is greater than. When greater the index is
+ decremented and the position is updated to the right child node.
+
+ 2. At node 9 with index 3, we again compare the index to the left-child
+ node with value 4. Because the index is the less than the left-child
+ node, we simply traverse to the left.
+
+ 3. At node 4 with index 3, we recognize that we are at a leaf node and
+ stop iterating.
+
+ 4. To compute the sublist index, we subtract the offset from the index
+ of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
+ simply use the index remaining from iteration. In this case, 3.
+
+ The final index pair from our example is (2, 3) which corresponds to
+ index 8 in the sorted list.
+ """
+ _len, _lists = self._len, self._lists
+
+ if idx < 0:
+ last_len = len(_lists[-1])
+ if (-idx) <= last_len:
+ return len(_lists) - 1, last_len + idx
+ idx += _len
+ if idx < 0:
+ raise IndexError('list index out of range')
+ elif idx >= _len:
+ raise IndexError('list index out of range')
+
+ if idx < len(_lists[0]):
+ return 0, idx
+
+ _index = self._index
+
+ if not len(_index):
+ self._build_index()
+
+ pos = 0
+ len_index = len(_index)
+ child = (pos << 1) + 1
+
+ while child < len_index:
+ index_child = _index[child]
+
+ if idx < index_child:
+ pos = child
+ else:
+ idx -= index_child
+ pos = child + 1
+
+ child = (pos << 1) + 1
+
+ return (pos - self._offset, idx)
+
+ def _build_index(self):
+ """Build an index for indexing the sorted list.
+
+ Indexes are represented as binary trees in a dense array notation
+ similar to a binary heap.
+
+ For example, given a _lists representation storing integers:
+
+ [0]: 1 2 3
+ [1]: 4 5
+ [2]: 6 7 8 9
+ [3]: 10 11 12 13 14
+
+ The first transformation maps the sub-lists by their length. The
+ first row of the index is the length of the sub-lists.
+
+ [0]: 3 2 4 5
+
+ Each row after that is the sum of consecutive pairs of the previous row:
+
+ [1]: 5 9
+ [2]: 14
+
+ Finally, the index is built by concatenating these lists together:
+
+ _index = 14 5 9 3 2 4 5
+
+ An offset storing the start of the first row is also stored:
+
+ _offset = 3
+
+ When built, the index can be used for efficient indexing into the list.
+ See the comment and notes on self._pos for details.
+ """
+ row0 = list(map(len, self._lists))
+
+ if len(row0) == 1:
+ self._index[:] = row0
+ self._offset = 0
+ return
+
+ head = iter(row0)
+ tail = iter(head)
+ row1 = list(starmap(add, zip(head, tail)))
+
+ if len(row0) & 1:
+ row1.append(row0[-1])
+
+ if len(row1) == 1:
+ self._index[:] = row1 + row0
+ self._offset = 1
+ return
+
+ size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
+ row1.extend(repeat(0, size - len(row1)))
+ tree = [row0, row1]
+
+ while len(tree[-1]) > 1:
+ head = iter(tree[-1])
+ tail = iter(head)
+ row = list(starmap(add, zip(head, tail)))
+ tree.append(row)
+
+ reduce(iadd, reversed(tree), self._index)
+ self._offset = size * 2 - 1
+
+ def _slice(self, slc):
+ start, stop, step = slc.start, slc.stop, slc.step
+
+ if step == 0:
+ raise ValueError('slice step cannot be zero')
+
+ # Set defaults for missing values.
+
+ if step is None:
+ step = 1
+
+ if step > 0:
+ if start is None:
+ start = 0
+
+ if stop is None:
+ stop = len(self)
+ elif stop < 0:
+ stop += len(self)
+ else:
+ if start is None:
+ start = len(self) - 1
+
+ if stop is None:
+ stop = -1
+ elif stop < 0:
+ stop += len(self)
+
+ if start < 0:
+ start += len(self)
+
+ # Fix indices that are too big or too small.
+ # Slice notation is surprisingly permissive
+ # where normal indexing would raise IndexError.
+
+ if step > 0:
+ if start < 0:
+ start = 0
+ elif start > len(self):
+ start = len(self)
+
+ if stop < 0:
+ stop = 0
+ elif stop > len(self):
+ stop = len(self)
+ else:
+ if start < 0:
+ start = -1
+ elif start >= len(self):
+ start = len(self) - 1
+
+ if stop < 0:
+ stop = -1
+ elif stop > len(self):
+ stop = len(self)
+
+ return start, stop, step
+
+ def __delitem__(self, idx):
+ """Remove the element at *idx*. Supports slicing."""
+ if isinstance(idx, slice):
+ start, stop, step = self._slice(idx)
+
+ if ((step == 1) and (start < stop)
+ and ((stop - start) * 8 >= self._len)):
+
+ values = self[:start]
+ if stop < self._len:
+ values += self[stop:]
+ self.clear()
+ self.update(values)
+ return
+
+ indices = range(start, stop, step)
+
+ # Delete items from greatest index to least so
+ # that the indices remain valid throughout iteration.
+
+ if step > 0:
+ indices = reversed(indices)
+
+ _pos, _delete = self._pos, self._delete
+
+ for index in indices:
+ pos, idx = _pos(index)
+ _delete(pos, idx)
+ else:
+ pos, idx = self._pos(idx)
+ self._delete(pos, idx)
+
+ def __getitem__(self, idx):
+ """Return the element at *idx*. Supports slicing."""
+ _lists = self._lists
+
+ if isinstance(idx, slice):
+ start, stop, step = self._slice(idx)
+
+ if step == 1 and start < stop:
+ if start == 0 and stop == self._len:
+ return self.as_list()
+
+ start_pos, start_idx = self._pos(start)
+
+ if stop == self._len:
+ stop_pos = len(_lists) - 1
+ stop_idx = len(_lists[stop_pos])
+ else:
+ stop_pos, stop_idx = self._pos(stop)
+
+ if start_pos == stop_pos:
+ return _lists[start_pos][start_idx:stop_idx]
+
+ prefix = _lists[start_pos][start_idx:]
+ middle = _lists[(start_pos + 1):stop_pos]
+ result = reduce(iadd, middle, prefix)
+ result += _lists[stop_pos][:stop_idx]
+
+ return result
+
+ if step == -1 and start > stop:
+ result = self[(stop + 1):(start + 1)]
+ result.reverse()
+ return result
+
+ # Return a list because a negative step could
+ # reverse the order of the items and this could
+ # be the desired behavior.
+
+ indices = range(start, stop, step)
+ return list(self[index] for index in indices)
+ else:
+ pos, idx = self._pos(idx)
+ return _lists[pos][idx]
+
+ def _check_order(self, idx, val):
+ _lists, _len = self._lists, self._len
+
+ pos, loc = self._pos(idx)
+
+ if idx < 0:
+ idx += _len
+
+ # Check that the inserted value is not less than the
+ # previous value.
+
+ if idx > 0:
+ idx_prev = loc - 1
+ pos_prev = pos
+
+ if idx_prev < 0:
+ pos_prev -= 1
+ idx_prev = len(_lists[pos_prev]) - 1
+
+ if _lists[pos_prev][idx_prev] > val:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ # Check that the inserted value is not greater than
+ # the previous value.
+
+ if idx < (_len - 1):
+ idx_next = loc + 1
+ pos_next = pos
+
+ if idx_next == len(_lists[pos_next]):
+ pos_next += 1
+ idx_next = 0
+
+ if _lists[pos_next][idx_next] < val:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ def __setitem__(self, index, value):
+ """
+ Replace the item at position *index* with *value*.
+
+ Supports slice notation. Raises a :exc:`ValueError` if the sort order
+ would be violated. When used with a slice and iterable, the
+ :exc:`ValueError` is raised before the list is mutated if the sort order
+ would be violated by the operation.
+ """
+ _maxes, _lists, _pos = self._maxes, self._lists, self._pos
+ _check_order = self._check_order
+
+ if isinstance(index, slice):
+ start, stop, step = self._slice(index)
+ indices = range(start, stop, step)
+
+ if step != 1:
+ if not hasattr(value, '__len__'):
+ value = list(value)
+
+ indices = list(indices)
+
+ if len(value) != len(indices):
+ raise ValueError(
+ 'attempt to assign sequence of size {0}'
+ ' to extended slice of size {1}'
+ .format(len(value), len(indices)))
+
+ # Keep a log of values that are set so that we can
+ # roll back changes if ordering is violated.
+
+ log = []
+ _append = log.append
+
+ for idx, val in zip(indices, value):
+ pos, loc = _pos(idx)
+ _append((idx, _lists[pos][loc], val))
+ _lists[pos][loc] = val
+ if len(_lists[pos]) == (loc + 1):
+ _maxes[pos] = val
+
+ try:
+ # Validate ordering of new values.
+
+ for idx, oldval, newval in log:
+ _check_order(idx, newval)
+
+ except ValueError:
+
+ # Roll back changes from log.
+
+ for idx, oldval, newval in log:
+ pos, loc = _pos(idx)
+ _lists[pos][loc] = oldval
+ if len(_lists[pos]) == (loc + 1):
+ _maxes[pos] = oldval
+
+ raise
+ else:
+ # Test ordering using indexing. If the value given
+ # doesn't support getitem, convert it to a list.
+
+ if not hasattr(value, '__getitem__'):
+ value = list(value)
+
+ # Check that the given values are ordered properly.
+
+ ordered = all(value[pos - 1] <= value[pos]
+ for pos in range(1, len(value)))
+
+ if not ordered:
+ raise ValueError('given sequence not in sort order')
+
+ # Check ordering in context of sorted list.
+
+ if not start or not len(value):
+ # Nothing to check on the lhs.
+ pass
+ else:
+ if self[start - 1] > value[0]:
+ msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
+ raise ValueError(msg)
+
+ if stop == len(self) or not len(value):
+ # Nothing to check on the rhs.
+ pass
+ else:
+ # "stop" is exclusive so we don't need
+ # to add one for the index.
+ if self[stop] < value[-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
+ raise ValueError(msg)
+
+ # Delete the existing values.
+
+ del self[index]
+
+ # Insert the new values.
+
+ _insert = self.insert
+ for idx, val in enumerate(value):
+ _insert(start + idx, val)
+ else:
+ pos, loc = _pos(index)
+ _check_order(index, value)
+ _lists[pos][loc] = value
+ if len(_lists[pos]) == (loc + 1):
+ _maxes[pos] = value
+
+ def __iter__(self):
+ """Create an iterator over the list."""
+ return chain.from_iterable(self._lists)
+
+ def __reversed__(self):
+ """Create an iterator to traverse the list in reverse."""
+ return chain.from_iterable(map(reversed, reversed(self._lists)))
+
+ def __len__(self):
+ """Return the number of elements in the list."""
+ return self._len
+
+ def bisect_left(self, val):
+ """
+ Similar to the *bisect* module in the standard library, this returns an
+ appropriate index to insert *val*. If *val* is already present, the
+ insertion point will be before (to the left of) any existing entries.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ pos = bisect_left(_maxes, val)
+
+ if pos == len(_maxes):
+ return self._len
+
+ idx = bisect_left(self._lists[pos], val)
+
+ return self._loc(pos, idx)
+
+ def bisect_right(self, val):
+ """
+ Same as *bisect_left*, but if *val* is already present, the insertion
+ point will be after (to the right of) any existing entries.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ pos = bisect_right(_maxes, val)
+
+ if pos == len(_maxes):
+ return self._len
+
+ idx = bisect_right(self._lists[pos], val)
+
+ return self._loc(pos, idx)
+
+ bisect = bisect_right
+
+ def count(self, val):
+ """Return the number of occurrences of *val* in the list."""
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ pos_left = bisect_left(_maxes, val)
+
+ if pos_left == len(_maxes):
+ return 0
+
+ _lists = self._lists
+ idx_left = bisect_left(_lists[pos_left], val)
+ pos_right = bisect_right(_maxes, val)
+
+ if pos_right == len(_maxes):
+ return self._len - self._loc(pos_left, idx_left)
+
+ idx_right = bisect_right(_lists[pos_right], val)
+
+ if pos_left == pos_right:
+ return idx_right - idx_left
+
+ right = self._loc(pos_right, idx_right)
+ left = self._loc(pos_left, idx_left)
+
+ return right - left
+
+ def copy(self):
+ """Return a shallow copy of the sorted list."""
+ return self.__class__(self, load=self._load)
+
+ __copy__ = copy
+
+ def append(self, val):
+ """
+ Append the element *val* to the list. Raises a ValueError if the *val*
+ would violate the sort order.
+ """
+ _maxes, _lists = self._maxes, self._lists
+
+ if not _maxes:
+ _maxes.append(val)
+ _lists.append([val])
+ self._len = 1
+ return
+
+ pos = len(_lists) - 1
+
+ if val < _lists[pos][-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
+ raise ValueError(msg)
+
+ _maxes[pos] = val
+ _lists[pos].append(val)
+ self._len += 1
+ self._expand(pos)
+
+ def extend(self, values):
+ """
+ Extend the list by appending all elements from the *values*. Raises a
+ ValueError if the sort order would be violated.
+ """
+ _maxes, _lists, _load = self._maxes, self._lists, self._load
+
+ if not isinstance(values, list):
+ values = list(values)
+
+ if any(values[pos - 1] > values[pos]
+ for pos in range(1, len(values))):
+ raise ValueError('given sequence not in sort order')
+
+ offset = 0
+
+ if _maxes:
+ if values[0] < _lists[-1][-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
+ raise ValueError(msg)
+
+ if len(_lists[-1]) < self._half:
+ _lists[-1].extend(values[:_load])
+ _maxes[-1] = _lists[-1][-1]
+ offset = _load
+
+ len_lists = len(_lists)
+
+ for idx in range(offset, len(values), _load):
+ _lists.append(values[idx:(idx + _load)])
+ _maxes.append(_lists[-1][-1])
+
+ _index = self._index
+
+ if len_lists == len(_lists):
+ len_index = len(_index)
+ if len_index > 0:
+ len_values = len(values)
+ child = len_index - 1
+ while child:
+ _index[child] += len_values
+ child = (child - 1) >> 1
+ _index[0] += len_values
+ else:
+ del _index[:]
+
+ self._len += len(values)
+
+ def insert(self, idx, val):
+ """
+ Insert the element *val* into the list at *idx*. Raises a ValueError if
+ the *val* at *idx* would violate the sort order.
+ """
+ _maxes, _lists, _len = self._maxes, self._lists, self._len
+
+ if idx < 0:
+ idx += _len
+ if idx < 0:
+ idx = 0
+ if idx > _len:
+ idx = _len
+
+ if not _maxes:
+ # The idx must be zero by the inequalities above.
+ _maxes.append(val)
+ _lists.append([val])
+ self._len = 1
+ return
+
+ if not idx:
+ if val > _lists[0][0]:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
+ raise ValueError(msg)
+ else:
+ _lists[0].insert(0, val)
+ self._expand(0)
+ self._len += 1
+ return
+
+ if idx == _len:
+ pos = len(_lists) - 1
+ if _lists[pos][-1] > val:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
+ raise ValueError(msg)
+ else:
+ _lists[pos].append(val)
+ _maxes[pos] = _lists[pos][-1]
+ self._expand(pos)
+ self._len += 1
+ return
+
+ pos, idx = self._pos(idx)
+ idx_before = idx - 1
+ if idx_before < 0:
+ pos_before = pos - 1
+ idx_before = len(_lists[pos_before]) - 1
+ else:
+ pos_before = pos
+
+ before = _lists[pos_before][idx_before]
+ if before <= val <= _lists[pos][idx]:
+ _lists[pos].insert(idx, val)
+ self._expand(pos)
+ self._len += 1
+ else:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ def pop(self, idx=-1):
+ """
+ Remove and return item at *idx* (default last). Raises IndexError if
+ list is empty or index is out of range. Negative indices are supported,
+ as for slice indices.
+ """
+ if (idx < 0 and -idx > self._len) or (idx >= self._len):
+ raise IndexError('pop index out of range')
+
+ pos, idx = self._pos(idx)
+ val = self._lists[pos][idx]
+ self._delete(pos, idx)
+
+ return val
+
+ def index(self, val, start=None, stop=None):
+ """
+ Return the smallest *k* such that L[k] == val and i <= k < j`. Raises
+ ValueError if *val* is not present. *stop* defaults to the end of the
+ list. *start* defaults to the beginning. Negative indices are supported,
+ as for slice indices.
+ """
+ _len, _maxes = self._len, self._maxes
+
+ if not _maxes:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ if start is None:
+ start = 0
+ if start < 0:
+ start += _len
+ if start < 0:
+ start = 0
+
+ if stop is None:
+ stop = _len
+ if stop < 0:
+ stop += _len
+ if stop > _len:
+ stop = _len
+
+ if stop <= start:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ stop -= 1
+ pos_left = bisect_left(_maxes, val)
+
+ if pos_left == len(_maxes):
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ _lists = self._lists
+ idx_left = bisect_left(_lists[pos_left], val)
+
+ if _lists[pos_left][idx_left] != val:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ left = self._loc(pos_left, idx_left)
+
+ if start <= left:
+ if left <= stop:
+ return left
+ else:
+ right = self.bisect_right(val) - 1
+
+ if start <= right:
+ return start
+
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ def as_list(self):
+ """Very efficiently convert the SortedList to a list."""
+ return reduce(iadd, self._lists, [])
+
+ def __add__(self, that):
+ """
+ Return a new sorted list containing all the elements in *self* and
+ *that*. Elements in *that* do not need to be properly ordered with
+ respect to *self*.
+ """
+ values = self.as_list()
+ values.extend(that)
+ return self.__class__(values, load=self._load)
+
+ def __iadd__(self, that):
+ """
+ Update *self* to include all values in *that*. Elements in *that* do not
+ need to be properly ordered with respect to *self*.
+ """
+ self.update(that)
+ return self
+
+ def __mul__(self, that):
+ """
+ Return a new sorted list containing *that* shallow copies of each item
+ in SortedList.
+ """
+ values = self.as_list() * that
+ return self.__class__(values, load=self._load)
+
+ def __imul__(self, that):
+ """
+ Increase the length of the list by appending *that* shallow copies of
+ each item.
+ """
+ values = self.as_list() * that
+ self.clear()
+ self.update(values)
+ return self
+
+ def __eq__(self, that):
+ """Compare two Sequences for equality."""
+ return ((self._len == len(that))
+ and all(lhs == rhs for lhs, rhs in zip(self, that)))
+
+ def __ne__(self, that):
+ """Compare two Sequences for inequality."""
+ return ((self._len != len(that))
+ or any(lhs != rhs for lhs, rhs in zip(self, that)))
+
+ def __lt__(self, that):
+ """Compare two Sequences for less than."""
+ return ((self._len <= len(that))
+ and all(lhs < rhs for lhs, rhs in zip(self, that)))
+
+ def __le__(self, that):
+ """Compare two Sequences for less than equal."""
+ return ((self._len <= len(that))
+ and all(lhs <= rhs for lhs, rhs in zip(self, that)))
+
+ def __gt__(self, that):
+ """Compare two Sequences for greater than."""
+ return ((self._len >= len(that))
+ and all(lhs > rhs for lhs, rhs in zip(self, that)))
+
+ def __ge__(self, that):
+ """Compare two Sequences for greater than equal."""
+ return ((self._len >= len(that))
+ and all(lhs >= rhs for lhs, rhs in zip(self, that)))
+
+ @recursive_repr
+ def __repr__(self):
+ """Return string representation of SortedList."""
+ temp = '{0}({1}, load={2})'
+ return temp.format(
+ self.__class__.__name__,
+ repr(list(self)),
+ repr(self._load)
+ )
+
+ def _check(self):
+ try:
+ # Check load parameters.
+
+ assert self._load >= 4
+ assert self._half == (self._load >> 1)
+ assert self._twice == (self._load * 2)
+
+ # Check empty sorted list case.
+
+ if self._maxes == []:
+ assert self._lists == []
+ return
+
+ assert len(self._maxes) > 0 and len(self._lists) > 0
+
+ # Check all sublists are sorted.
+
+ assert all(sublist[pos - 1] <= sublist[pos]
+ for sublist in self._lists
+ for pos in range(1, len(sublist)))
+
+ # Check beginning/end of sublists are sorted.
+
+ for pos in range(1, len(self._lists)):
+ assert self._lists[pos - 1][-1] <= self._lists[pos][0]
+
+ # Check length of _maxes and _lists match.
+
+ assert len(self._maxes) == len(self._lists)
+
+ # Check _maxes is a map of _lists.
+
+ assert all(self._maxes[pos] == self._lists[pos][-1]
+ for pos in range(len(self._maxes)))
+
+ # Check load level is less than _twice.
+
+ assert all(len(sublist) <= self._twice for sublist in self._lists)
+
+ # Check load level is greater than _half for all
+ # but the last sublist.
+
+ assert all(len(self._lists[pos]) >= self._half
+ for pos in range(0, len(self._lists) - 1))
+
+ # Check length.
+
+ assert self._len == sum(len(sublist) for sublist in self._lists)
+
+ # Check index.
+
+ if len(self._index):
+ assert len(self._index) == self._offset + len(self._lists)
+ assert self._len == self._index[0]
+
+ def test_offset_pos(pos):
+ from_index = self._index[self._offset + pos]
+ return from_index == len(self._lists[pos])
+
+ assert all(test_offset_pos(pos)
+ for pos in range(len(self._lists)))
+
+ for pos in range(self._offset):
+ child = (pos << 1) + 1
+ if self._index[pos] == 0:
+ assert child >= len(self._index)
+ elif child + 1 == len(self._index):
+ assert self._index[pos] == self._index[child]
+ else:
+ child_sum = self._index[child] + self._index[child + 1]
+ assert self._index[pos] == child_sum
+
+ except:
+ import sys
+ import traceback
+
+ traceback.print_exc(file=sys.stdout)
+
+ print('len', self._len)
+ print('load', self._load, self._half, self._twice)
+ print('offset', self._offset)
+ print('len_index', len(self._index))
+ print('index', self._index)
+ print('len_maxes', len(self._maxes))
+ print('maxes', self._maxes)
+ print('len_lists', len(self._lists))
+ print('lists', self._lists)
+
+ raise
diff --git a/src/sortedcontainers/sortedlistwithkey.py b/src/sortedcontainers/sortedlistwithkey.py
new file mode 100755
index 0000000..688cf1f
--- /dev/null
+++ b/src/sortedcontainers/sortedlistwithkey.py
@@ -0,0 +1,1331 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted list implementation.
+
+from __future__ import print_function
+from sys import hexversion
+
+from .sortedlist import recursive_repr
+from bisect import bisect_left, bisect_right, insort
+from itertools import chain, repeat, starmap
+from collections import MutableSequence
+from operator import iadd, add
+from functools import wraps
+from math import log
+
+if hexversion < 0x03000000:
+ from itertools import izip as zip
+ from itertools import imap as map
+else:
+ from functools import reduce
+
+def identity(value):
+ return value
+
+class SortedListWithKey(MutableSequence):
+ """
+ SortedList provides most of the same methods as a list but keeps the items
+ in sorted order.
+ """
+
+ def __init__(self, iterable=None, key=identity, load=1000):
+ """
+ SortedList provides most of the same methods as a list but keeps the
+ items in sorted order.
+
+ An optional *iterable* provides an initial series of items to populate
+ the SortedList.
+
+ An optional *load* specifies the load-factor of the list. The default
+ load factor of '1000' works well for lists from tens to tens of millions
+ of elements. Good practice is to use a value that is the cube root of
+ the list size. With billions of elements, the best load factor depends
+ on your usage. It's best to leave the load factor at the default until
+ you start benchmarking.
+ """
+ self._len, self._maxes, self._lists, self._keys, self._index = 0, [], [], [], []
+ self._key, self._load, self._twice, self._half = key, load, load * 2, load >> 1
+ self._offset = 0
+
+ if iterable is not None:
+ self.update(iterable)
+
+ def clear(self):
+ """Remove all the elements from the list."""
+ self._len = 0
+ del self._maxes[:]
+ del self._lists[:]
+ del self._keys[:]
+ del self._index[:]
+
+ def add(self, val):
+ """Add the element *val* to the list."""
+ _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+
+ key = self._key(val)
+
+ if _maxes:
+ pos = bisect_right(_maxes, key)
+
+ if pos == len(_maxes):
+ pos -= 1
+ _maxes[pos] = key
+ _keys[pos].append(key)
+ _lists[pos].append(val)
+ else:
+ idx = bisect_right(_keys[pos], key)
+ _keys[pos].insert(idx, key)
+ _lists[pos].insert(idx, val)
+
+ self._expand(pos)
+ else:
+ _maxes.append(key)
+ _keys.append([key])
+ _lists.append([val])
+
+ self._len += 1
+
+ def _expand(self, pos):
+ """
+ Splits sublists that are more than double the load level.
+
+ Updates the index when the sublist length is less than double the load
+ level. This requires incrementing the nodes in a traversal from the leaf
+ node to the root. For an example traversal see self._loc.
+ """
+ _lists, _keys, _index = self._lists, self._keys, self._index
+
+ if len(_keys[pos]) > self._twice:
+ _maxes, _load = self._maxes, self._load
+
+ half = _keys[pos][_load:]
+ half_list = _lists[pos][_load:]
+ del _keys[pos][_load:]
+ del _lists[pos][_load:]
+ _maxes[pos] = _keys[pos][-1]
+
+ _maxes.insert(pos + 1, half[-1])
+ _keys.insert(pos + 1, half)
+ _lists.insert(pos + 1, half_list)
+
+ del _index[:]
+ else:
+ if len(_index) > 0:
+ child = self._offset + pos
+ while child > 0:
+ _index[child] += 1
+ child = (child - 1) >> 1
+ _index[0] += 1
+
+ def update(self, iterable):
+ """Update the list by adding all elements from *iterable*."""
+ _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+ values = sorted(iterable, key=self._key)
+
+ if _maxes:
+ if len(values) * 4 >= self._len:
+ values.extend(chain.from_iterable(_lists))
+ values.sort(key=self._key)
+ self.clear()
+ else:
+ _add = self.add
+ for val in values:
+ _add(val)
+ return
+
+ _load, _index = self._load, self._index
+ _lists.extend(values[pos:(pos + _load)]
+ for pos in range(0, len(values), _load))
+ _keys.extend(list(map(self._key, _list)) for _list in _lists)
+ _maxes.extend(sublist[-1] for sublist in _keys)
+ self._len = len(values)
+ del _index[:]
+
+ def __contains__(self, val):
+ """Return True if and only if *val* is an element in the list."""
+ _maxes = self._maxes
+
+ if not _maxes:
+ return False
+
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ return False
+
+ _keys = self._keys
+ _lists = self._lists
+
+ idx = bisect_left(_keys[pos], key)
+
+ len_keys = len(_keys)
+ len_sublist = len(_keys[pos])
+
+ while True:
+ if _keys[pos][idx] != key:
+ return False
+ if _lists[pos][idx] == val:
+ return True
+ idx += 1
+ if idx == len_sublist:
+ pos += 1
+ if pos == len_keys:
+ return False
+ len_sublist = len(_keys[pos])
+ idx = 0
+
+ def discard(self, val):
+ """
+ Remove the first occurrence of *val*.
+
+ If *val* is not a member, does nothing.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return
+
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ return
+
+ _keys = self._keys
+ _lists = self._lists
+ idx = bisect_left(_keys[pos], key)
+
+ len_keys = len(_keys)
+ len_sublist = len(_keys[pos])
+
+ while True:
+ if _keys[pos][idx] != key:
+ return
+ if _lists[pos][idx] == val:
+ self._delete(pos, idx)
+ return
+ idx += 1
+ if idx == len_sublist:
+ pos += 1
+ if pos == len_keys:
+ return
+ len_sublist = len(_keys[pos])
+ idx = 0
+
+ def remove(self, val):
+ """
+ Remove first occurrence of *val*.
+
+ Raises ValueError if *val* is not present.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ raise ValueError('{0} not in list'.format(repr(val)))
+
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ raise ValueError('{0} not in list'.format(repr(val)))
+
+ _keys = self._keys
+ _lists = self._lists
+ idx = bisect_left(_keys[pos], key)
+
+ len_keys = len(_keys)
+ len_sublist = len(_keys[pos])
+
+ while True:
+ if _keys[pos][idx] != key:
+ raise ValueError('{0} not in list'.format(repr(val)))
+ if _lists[pos][idx] == val:
+ self._delete(pos, idx)
+ return
+ idx += 1
+ if idx == len_sublist:
+ pos += 1
+ if pos == len_keys:
+ raise ValueError('{0} not in list'.format(repr(val)))
+ len_sublist = len(_keys[pos])
+ idx = 0
+
+ def _delete(self, pos, idx):
+ """
+ Delete the item at the given (pos, idx).
+
+ Combines lists that are less than half the load level.
+
+ Updates the index when the sublist length is more than half the load
+ level. This requires decrementing the nodes in a traversal from the leaf
+ node to the root. For an example traversal see self._loc.
+ """
+ _maxes, _lists, _keys, _index = self._maxes, self._lists, self._keys, self._index
+
+ keys_pos = _keys[pos]
+ lists_pos = _lists[pos]
+
+ del keys_pos[idx]
+ del lists_pos[idx]
+ self._len -= 1
+
+ len_keys_pos = len(keys_pos)
+
+ if len_keys_pos > self._half:
+
+ _maxes[pos] = keys_pos[-1]
+
+ if len(_index) > 0:
+ child = self._offset + pos
+ while child > 0:
+ _index[child] -= 1
+ child = (child - 1) >> 1
+ _index[0] -= 1
+
+ elif len(_keys) > 1:
+
+ if not pos:
+ pos += 1
+
+ prev = pos - 1
+ _keys[prev].extend(_keys[pos])
+ _lists[prev].extend(_lists[pos])
+ _maxes[prev] = _keys[prev][-1]
+
+ del _keys[pos]
+ del _lists[pos]
+ del _maxes[pos]
+ del _index[:]
+
+ self._expand(prev)
+
+ elif len_keys_pos:
+
+ _maxes[pos] = keys_pos[-1]
+
+ else:
+
+ del _keys[pos]
+ del _lists[pos]
+ del _maxes[pos]
+ del _index[:]
+
+ def _loc(self, pos, idx):
+ """Convert an index pair (alpha, beta) into a single index that corresponds to
+ the position of the value in the sorted list.
+
+ Most queries require the index be built. Details of the index are
+ described in self._build_index.
+
+ Indexing requires traversing the tree from a leaf node to the root. The
+ parent of each node is easily computable at (pos - 1) // 2.
+
+ Left-child nodes are always at odd indices and right-child nodes are
+ always at even indices.
+
+ When traversing up from a right-child node, increment the total by the
+ left-child node.
+
+ The final index is the sum from traversal and the index in the sublist.
+
+ For example, using the index from self._build_index:
+
+ _index = 14 5 9 3 2 4 5
+ _offset = 3
+
+ Tree:
+
+ 14
+ 5 9
+ 3 2 4 5
+
+ Converting index pair (2, 3) into a single index involves iterating like
+ so:
+
+ 1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
+ the node as a left-child node. At such nodes, we simply traverse to
+ the parent.
+
+ 2. At node 9, position 2, we recognize the node as a right-child node
+ and accumulate the left-child in our total. Total is now 5 and we
+ traverse to the parent at position 0.
+
+ 3. Iteration ends at the root.
+
+ Computing the index is the sum of the total and beta: 5 + 3 = 8.
+ """
+ if not pos:
+ return idx
+
+ _index = self._index
+
+ if not len(_index):
+ self._build_index()
+
+ total = 0
+
+ # Increment pos to point in the index to len(self._lists[pos]).
+
+ pos += self._offset
+
+ # Iterate until reaching the root of the index tree at pos = 0.
+
+ while pos:
+
+ # Right-child nodes are at odd indices. At such indices
+ # account the total below the left child node.
+
+ if not (pos & 1):
+ total += _index[pos - 1]
+
+ # Advance pos to the parent node.
+
+ pos = (pos - 1) >> 1
+
+ return total + idx
+
+ def _pos(self, idx):
+ """Convert an index into a pair (alpha, beta) that can be used to access
+ the corresponding _lists[alpha][beta] position.
+
+ Most queries require the index be built. Details of the index are
+ described in self._build_index.
+
+ Indexing requires traversing the tree to a leaf node. Each node has
+ two children which are easily computable. Given an index, pos, the
+ left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
+
+ When the index is less than the left-child, traversal moves to the
+ left sub-tree. Otherwise, the index is decremented by the left-child
+ and traversal moves to the right sub-tree.
+
+ At a child node, the indexing pair is computed from the relative
+ position of the child node as compared with the offset and the remaining
+ index.
+
+ For example, using the index from self._build_index:
+
+ _index = 14 5 9 3 2 4 5
+ _offset = 3
+
+ Tree:
+
+ 14
+ 5 9
+ 3 2 4 5
+
+ Indexing position 8 involves iterating like so:
+
+ 1. Starting at the root, position 0, 8 is compared with the left-child
+ node (5) which it is greater than. When greater the index is
+ decremented and the position is updated to the right child node.
+
+ 2. At node 9 with index 3, we again compare the index to the left-child
+ node with value 4. Because the index is the less than the left-child
+ node, we simply traverse to the left.
+
+ 3. At node 4 with index 3, we recognize that we are at a leaf node and
+ stop iterating.
+
+ 4. To compute the sublist index, we subtract the offset from the index
+ of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
+ simply use the index remaining from iteration. In this case, 3.
+
+ The final index pair from our example is (2, 3) which corresponds to
+ index 8 in the sorted list.
+ """
+ _len, _lists = self._len, self._lists
+
+ if idx < 0:
+ last_len = len(_lists[-1])
+ if (-idx) <= last_len:
+ return len(_lists) - 1, last_len + idx
+ idx += _len
+ if idx < 0:
+ raise IndexError('list index out of range')
+ elif idx >= _len:
+ raise IndexError('list index out of range')
+
+ if idx < len(_lists[0]):
+ return 0, idx
+
+ _index = self._index
+
+ if not len(_index):
+ self._build_index()
+
+ pos = 0
+ len_index = len(_index)
+ child = (pos << 1) + 1
+
+ while child < len_index:
+ index_child = _index[child]
+
+ if idx < index_child:
+ pos = child
+ else:
+ idx -= index_child
+ pos = child + 1
+
+ child = (pos << 1) + 1
+
+ return (pos - self._offset, idx)
+
+ def _build_index(self):
+ """Build an index for indexing the sorted list.
+
+ Indexes are represented as binary trees in a dense array notation
+ similar to a binary heap.
+
+ For example, given a _lists representation storing integers:
+
+ [0]: 1 2 3
+ [1]: 4 5
+ [2]: 6 7 8 9
+ [3]: 10 11 12 13 14
+
+ The first transformation maps the sub-lists by their length. The
+ first row of the index is the length of the sub-lists.
+
+ [0]: 3 2 4 5
+
+ Each row after that is the sum of consecutive pairs of the previous row:
+
+ [1]: 5 9
+ [2]: 14
+
+ Finally, the index is built by concatenating these lists together:
+
+ _index = 14 5 9 3 2 4 5
+
+ An offset storing the start of the first row is also stored:
+
+ _offset = 3
+
+ When built, the index can be used for efficient indexing into the list.
+ See the comment and notes on self._pos for details.
+ """
+ row0 = list(map(len, self._lists))
+
+ if len(row0) == 1:
+ self._index[:] = row0
+ self._offset = 0
+ return
+
+ head = iter(row0)
+ tail = iter(head)
+ row1 = list(starmap(add, zip(head, tail)))
+
+ if len(row0) & 1:
+ row1.append(row0[-1])
+
+ if len(row1) == 1:
+ self._index[:] = row1 + row0
+ self._offset = 1
+ return
+
+ size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
+ row1.extend(repeat(0, size - len(row1)))
+ tree = [row0, row1]
+
+ while len(tree[-1]) > 1:
+ head = iter(tree[-1])
+ tail = iter(head)
+ row = list(starmap(add, zip(head, tail)))
+ tree.append(row)
+
+ reduce(iadd, reversed(tree), self._index)
+ self._offset = size * 2 - 1
+
+ def _slice(self, slc):
+ start, stop, step = slc.start, slc.stop, slc.step
+
+ if step == 0:
+ raise ValueError('slice step cannot be zero')
+
+ # Set defaults for missing values.
+
+ if step is None:
+ step = 1
+
+ if step > 0:
+ if start is None:
+ start = 0
+
+ if stop is None:
+ stop = len(self)
+ elif stop < 0:
+ stop += len(self)
+ else:
+ if start is None:
+ start = len(self) - 1
+
+ if stop is None:
+ stop = -1
+ elif stop < 0:
+ stop += len(self)
+
+ if start < 0:
+ start += len(self)
+
+ # Fix indices that are too big or too small.
+ # Slice notation is surprisingly permissive
+ # where normal indexing would raise IndexError.
+
+ if step > 0:
+ if start < 0:
+ start = 0
+ elif start > len(self):
+ start = len(self)
+
+ if stop < 0:
+ stop = 0
+ elif stop > len(self):
+ stop = len(self)
+ else:
+ if start < 0:
+ start = -1
+ elif start >= len(self):
+ start = len(self) - 1
+
+ if stop < 0:
+ stop = -1
+ elif stop > len(self):
+ stop = len(self)
+
+ return start, stop, step
+
+ def __delitem__(self, idx):
+ """Remove the element at *idx*. Supports slicing."""
+ if isinstance(idx, slice):
+ start, stop, step = self._slice(idx)
+
+ if ((step == 1) and (start < stop)
+ and ((stop - start) * 8 >= self._len)):
+
+ values = self[:start]
+ if stop < self._len:
+ values += self[stop:]
+ self.clear()
+ self.update(values)
+ return
+
+ indices = range(start, stop, step)
+
+ # Delete items from greatest index to least so
+ # that the indices remain valid throughout iteration.
+
+ if step > 0:
+ indices = reversed(indices)
+
+ _pos, _delete = self._pos, self._delete
+
+ for index in indices:
+ pos, idx = _pos(index)
+ _delete(pos, idx)
+ else:
+ pos, idx = self._pos(idx)
+ self._delete(pos, idx)
+
+ def __getitem__(self, idx):
+ """Return the element at *idx*. Supports slicing."""
+ _lists = self._lists
+
+ if isinstance(idx, slice):
+ start, stop, step = self._slice(idx)
+
+ if step == 1 and start < stop:
+ if start == 0 and stop == self._len:
+ return self.as_list()
+
+ start_pos, start_idx = self._pos(start)
+
+ if stop == self._len:
+ stop_pos = len(_lists) - 1
+ stop_idx = len(_lists[stop_pos])
+ else:
+ stop_pos, stop_idx = self._pos(stop)
+
+ if start_pos == stop_pos:
+ return _lists[start_pos][start_idx:stop_idx]
+
+ prefix = _lists[start_pos][start_idx:]
+ middle = _lists[(start_pos + 1):stop_pos]
+ result = reduce(iadd, middle, prefix)
+ result += _lists[stop_pos][:stop_idx]
+
+ return result
+
+ if step == -1 and start > stop:
+ result = self[(stop + 1):(start + 1)]
+ result.reverse()
+ return result
+
+ # Return a list because a negative step could
+ # reverse the order of the items and this could
+ # be the desired behavior.
+
+ indices = range(start, stop, step)
+ return list(self[index] for index in indices)
+ else:
+ pos, idx = self._pos(idx)
+ return _lists[pos][idx]
+
+ def _check_order(self, idx, key, val):
+ _keys, _len = self._keys, self._len
+
+ pos, loc = self._pos(idx)
+
+ if idx < 0:
+ idx += _len
+
+ # Check that the inserted value is not less than the
+ # previous value.
+
+ if idx > 0:
+ idx_prev = loc - 1
+ pos_prev = pos
+
+ if idx_prev < 0:
+ pos_prev -= 1
+ idx_prev = len(_keys[pos_prev]) - 1
+
+ if _keys[pos_prev][idx_prev] > key:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ # Check that the inserted value is not greater than
+ # the previous value.
+
+ if idx < (_len - 1):
+ idx_next = loc + 1
+ pos_next = pos
+
+ if idx_next == len(_keys[pos_next]):
+ pos_next += 1
+ idx_next = 0
+
+ if _keys[pos_next][idx_next] < key:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ def __setitem__(self, index, value):
+ """
+ Replace the item at position *index* with *value*.
+
+ Supports slice notation. Raises a :exc:`ValueError` if the sort order
+ would be violated. When used with a slice and iterable, the
+ :exc:`ValueError` is raised before the list is mutated if the sort order
+ would be violated by the operation.
+ """
+ _maxes, _lists, _keys, _pos = self._maxes, self._lists, self._keys, self._pos
+ _check_order = self._check_order
+
+ if isinstance(index, slice):
+ start, stop, step = self._slice(index)
+ indices = range(start, stop, step)
+
+ if step != 1:
+ if not hasattr(value, '__len__'):
+ value = list(value)
+
+ indices = list(indices)
+
+ if len(value) != len(indices):
+ raise ValueError(
+ 'attempt to assign sequence of size {0}'
+ ' to extended slice of size {1}'
+ .format(len(value), len(indices)))
+
+ # Keep a log of values that are set so that we can
+ # roll back changes if ordering is violated.
+
+ log = []
+ _append = log.append
+
+ for idx, val in zip(indices, value):
+ pos, loc = _pos(idx)
+ key = self._key(val)
+ _append((idx, _keys[pos][loc], key, _lists[pos][loc], val))
+ _keys[pos][loc] = key
+ _lists[pos][loc] = val
+ if len(_keys[pos]) == (loc + 1):
+ _maxes[pos] = key
+
+ try:
+ # Validate ordering of new values.
+
+ for idx, oldkey, newkey, oldval, newval in log:
+ _check_order(idx, newkey, newval)
+
+ except ValueError:
+
+ # Roll back changes from log.
+
+ for idx, oldkey, newkey, oldval, newval in log:
+ pos, loc = _pos(idx)
+ _keys[pos][loc] = oldkey
+ _lists[pos][loc] = oldval
+ if len(_keys[pos]) == (loc + 1):
+ _maxes[pos] = oldkey
+
+ raise
+ else:
+ # Test ordering using indexing. If the value given
+ # doesn't support getitem, convert it to a list.
+
+ if not hasattr(value, '__getitem__'):
+ value = list(value)
+
+ # Check that the given values are ordered properly.
+
+ keys = list(map(self._key, value))
+ ordered = all(keys[pos - 1] <= keys[pos]
+ for pos in range(1, len(keys)))
+
+ if not ordered:
+ raise ValueError('given sequence not in sort order')
+
+ # Check ordering in context of sorted list.
+
+ if not start or not len(value):
+ # Nothing to check on the lhs.
+ pass
+ else:
+ pos, loc = _pos(start - 1)
+ if _keys[pos][loc] > keys[0]:
+ msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
+ raise ValueError(msg)
+
+ if stop == len(self) or not len(value):
+ # Nothing to check on the rhs.
+ pass
+ else:
+ # "stop" is exclusive so we don't need
+ # to add one for the index.
+ pos, loc = _pos(stop)
+ if _keys[pos][loc] < keys[-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
+ raise ValueError(msg)
+
+ # Delete the existing values.
+
+ del self[index]
+
+ # Insert the new values.
+
+ _insert = self.insert
+ for idx, val in enumerate(value):
+ _insert(start + idx, val)
+ else:
+ pos, loc = _pos(index)
+ key = self._key(value)
+ _check_order(index, key, value)
+ _keys[pos][loc] = key
+ _lists[pos][loc] = value
+ if len(_lists[pos]) == (loc + 1):
+ _maxes[pos] = key
+
+ def __iter__(self):
+ """Create an iterator over the list."""
+ return chain.from_iterable(self._lists)
+
+ def __reversed__(self):
+ """Create an iterator to traverse the list in reverse."""
+ return chain.from_iterable(map(reversed, reversed(self._lists)))
+
+ def __len__(self):
+ """Return the number of elements in the list."""
+ return self._len
+
+ def bisect_left(self, val):
+ """
+ Similar to the *bisect* module in the standard library, this returns an
+ appropriate index to insert *val*. If *val* is already present, the
+ insertion point will be before (to the left of) any existing entries.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ return self._len
+
+ idx = bisect_left(self._keys[pos], key)
+
+ return self._loc(pos, idx)
+
+ def bisect_right(self, val):
+ """
+ Same as *bisect_left*, but if *val* is already present, the insertion
+ point will be after (to the right of) any existing entries.
+ """
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ key = self._key(val)
+ pos = bisect_right(_maxes, key)
+
+ if pos == len(_maxes):
+ return self._len
+
+ idx = bisect_right(self._keys[pos], key)
+
+ return self._loc(pos, idx)
+
+ bisect = bisect_right
+
+ def count(self, val):
+ """Return the number of occurrences of *val* in the list."""
+ _maxes = self._maxes
+
+ if not _maxes:
+ return 0
+
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ return 0
+
+ _keys = self._keys
+ _lists = self._lists
+
+ idx = bisect_left(_keys[pos], key)
+
+ total = 0
+ len_keys = len(_keys)
+ len_sublist = len(_keys[pos])
+
+ while True:
+ if _keys[pos][idx] != key:
+ return total
+ if _lists[pos][idx] == val:
+ total += 1
+ idx += 1
+ if idx == len_sublist:
+ pos += 1
+ if pos == len_keys:
+ return total
+ len_sublist = len(_keys[pos])
+ idx = 0
+
+ def copy(self):
+ """Return a shallow copy of the sorted list."""
+ return self.__class__(self, key=self._key, load=self._load)
+
+ __copy__ = copy
+
+ def append(self, val):
+ """
+ Append the element *val* to the list. Raises a ValueError if the *val*
+ would violate the sort order.
+ """
+ _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+
+ key = self._key(val)
+
+ if not _maxes:
+ _maxes.append(key)
+ _keys.append([key])
+ _lists.append([val])
+ self._len = 1
+ return
+
+ pos = len(_keys) - 1
+
+ if key < _keys[pos][-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
+ raise ValueError(msg)
+
+ _maxes[pos] = key
+ _keys[pos].append(key)
+ _lists[pos].append(val)
+ self._len += 1
+ self._expand(pos)
+
+ def extend(self, values):
+ """
+ Extend the list by appending all elements from the *values*. Raises a
+ ValueError if the sort order would be violated.
+ """
+ _maxes, _keys, _lists, _load = self._maxes, self._keys, self._lists, self._load
+
+ if not isinstance(values, list):
+ values = list(values)
+
+ keys = list(map(self._key, values))
+
+ if any(keys[pos - 1] > keys[pos]
+ for pos in range(1, len(keys))):
+ raise ValueError('given sequence not in sort order')
+
+ offset = 0
+
+ if _maxes:
+ if keys[0] < _keys[-1][-1]:
+ msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
+ raise ValueError(msg)
+
+ if len(_keys[-1]) < self._half:
+ _lists[-1].extend(values[:_load])
+ _keys[-1].extend(keys[:_load])
+ _maxes[-1] = _keys[-1][-1]
+ offset = _load
+
+ len_keys = len(_keys)
+
+ for idx in range(offset, len(keys), _load):
+ _lists.append(values[idx:(idx + _load)])
+ _keys.append(keys[idx:(idx + _load)])
+ _maxes.append(_keys[-1][-1])
+
+ _index = self._index
+
+ if len_keys == len(_keys):
+ len_index = len(_index)
+ if len_index > 0:
+ len_values = len(values)
+ child = len_index - 1
+ while child:
+ _index[child] += len_values
+ child = (child - 1) >> 1
+ _index[0] += len_values
+ else:
+ del _index[:]
+
+ self._len += len(values)
+
+ def insert(self, idx, val):
+ """
+ Insert the element *val* into the list at *idx*. Raises a ValueError if
+ the *val* at *idx* would violate the sort order.
+ """
+ _maxes, _lists, _keys, _len = self._maxes, self._lists, self._keys, self._len
+
+ if idx < 0:
+ idx += _len
+ if idx < 0:
+ idx = 0
+ if idx > _len:
+ idx = _len
+
+ key = self._key(val)
+
+ if not _maxes:
+ # The idx must be zero by the inequalities above.
+ _maxes.append(key)
+ _lists.append([val])
+ _keys.append([key])
+ self._len = 1
+ return
+
+ if not idx:
+ if key > _keys[0][0]:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
+ raise ValueError(msg)
+ else:
+ _keys[0].insert(0, key)
+ _lists[0].insert(0, val)
+ self._expand(0)
+ self._len += 1
+ return
+
+ if idx == _len:
+ pos = len(_keys) - 1
+ if _keys[pos][-1] > key:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
+ raise ValueError(msg)
+ else:
+ _keys[pos].append(key)
+ _lists[pos].append(val)
+ _maxes[pos] = _keys[pos][-1]
+ self._expand(pos)
+ self._len += 1
+ return
+
+ pos, idx = self._pos(idx)
+ idx_before = idx - 1
+ if idx_before < 0:
+ pos_before = pos - 1
+ idx_before = len(_keys[pos_before]) - 1
+ else:
+ pos_before = pos
+
+ before = _keys[pos_before][idx_before]
+ if before <= key <= _keys[pos][idx]:
+ _lists[pos].insert(idx, val)
+ _keys[pos].insert(idx, key)
+ self._expand(pos)
+ self._len += 1
+ else:
+ msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+ raise ValueError(msg)
+
+ def pop(self, idx=-1):
+ """
+ Remove and return item at *idx* (default last). Raises IndexError if
+ list is empty or index is out of range. Negative indices are supported,
+ as for slice indices.
+ """
+ if (idx < 0 and -idx > self._len) or (idx >= self._len):
+ raise IndexError('pop index out of range')
+
+ pos, idx = self._pos(idx)
+ val = self._lists[pos][idx]
+ self._delete(pos, idx)
+
+ return val
+
+ def index(self, val, start=None, stop=None):
+ """
+ Return the smallest *k* such that L[k] == val and i <= k < j`. Raises
+ ValueError if *val* is not present. *stop* defaults to the end of the
+ list. *start* defaults to the beginning. Negative indices are supported,
+ as for slice indices.
+ """
+ _len, _maxes = self._len, self._maxes
+
+ if not _maxes:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ if start is None:
+ start = 0
+ if start < 0:
+ start += _len
+ if start < 0:
+ start = 0
+
+ if stop is None:
+ stop = _len
+ if stop < 0:
+ stop += _len
+ if stop > _len:
+ stop = _len
+
+ if stop <= start:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ stop -= 1
+ key = self._key(val)
+ pos = bisect_left(_maxes, key)
+
+ if pos == len(_maxes):
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ _keys = self._keys
+ _lists = self._lists
+
+ idx = bisect_left(_keys[pos], key)
+
+ len_keys = len(_keys)
+ len_sublist = len(_keys[pos])
+
+ while True:
+ if _keys[pos][idx] != key:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+ if _lists[pos][idx] == val:
+ loc = self._loc(pos, idx)
+ if start <= loc <= stop:
+ return loc
+ elif loc > stop:
+ break
+ idx += 1
+ if idx == len_sublist:
+ pos += 1
+ if pos == len_keys:
+ raise ValueError('{0} is not in list'.format(repr(val)))
+ len_sublist = len(_keys[pos])
+ idx = 0
+
+ raise ValueError('{0} is not in list'.format(repr(val)))
+
+ def as_list(self):
+ """Very efficiently convert the SortedList to a list."""
+ return reduce(iadd, self._lists, [])
+
+ def __add__(self, that):
+ """
+ Return a new sorted list containing all the elements in *self* and
+ *that*. Elements in *that* do not need to be properly ordered with
+ respect to *self*.
+ """
+ values = self.as_list()
+ values.extend(that)
+ return self.__class__(values, key=self._key, load=self._load)
+
+ def __iadd__(self, that):
+ """
+ Update *self* to include all values in *that*. Elements in *that* do not
+ need to be properly ordered with respect to *self*.
+ """
+ self.update(that)
+ return self
+
+ def __mul__(self, that):
+ """
+ Return a new sorted list containing *that* shallow copies of each item
+ in SortedList.
+ """
+ values = self.as_list() * that
+ return self.__class__(values, key=self._key, load=self._load)
+
+ def __imul__(self, that):
+ """
+ Increase the length of the list by appending *that* shallow copies of
+ each item.
+ """
+ values = self.as_list() * that
+ self.clear()
+ self.update(values)
+ return self
+
+ def __eq__(self, that):
+ """Compare two Sequences for equality."""
+ return ((self._len == len(that))
+ and all(lhs == rhs for lhs, rhs in zip(self, that)))
+
+ def __ne__(self, that):
+ """Compare two Sequences for inequality."""
+ return ((self._len != len(that))
+ or any(lhs != rhs for lhs, rhs in zip(self, that)))
+
+ def __lt__(self, that):
+ """Compare two Sequences for less than."""
+ return ((self._len <= len(that))
+ and all(lhs < rhs for lhs, rhs in zip(self, that)))
+
+ def __le__(self, that):
+ """Compare two Sequences for less than equal."""
+ return ((self._len <= len(that))
+ and all(lhs <= rhs for lhs, rhs in zip(self, that)))
+
+ def __gt__(self, that):
+ """Compare two Sequences for greater than."""
+ return ((self._len >= len(that))
+ and all(lhs > rhs for lhs, rhs in zip(self, that)))
+
+ def __ge__(self, that):
+ """Compare two Sequences for greater than equal."""
+ return ((self._len >= len(that))
+ and all(lhs >= rhs for lhs, rhs in zip(self, that)))
+
+ @recursive_repr
+ def __repr__(self):
+ """Return string representation of SortedListWithKey."""
+ temp = '{0}({1}, key={2}, load={3})'
+ return temp.format(
+ self.__class__.__name__,
+ repr(list(self)),
+ repr(self._key),
+ repr(self._load)
+ )
+
+ def _check(self):
+ try:
+ # Check load parameters.
+
+ assert self._load >= 4
+ assert self._half == (self._load >> 1)
+ assert self._twice == (self._load * 2)
+
+ # Check empty sorted list case.
+
+ if self._maxes == []:
+ assert self._keys == []
+ assert self._lists == []
+ return
+
+ assert len(self._maxes) > 0 and len(self._keys) > 0 and len(self._lists) > 0
+
+ # Check all sublists are sorted.
+
+ assert all(sublist[pos - 1] <= sublist[pos]
+ for sublist in self._keys
+ for pos in range(1, len(sublist)))
+
+ # Check beginning/end of sublists are sorted.
+
+ for pos in range(1, len(self._keys)):
+ assert self._keys[pos - 1][-1] <= self._keys[pos][0]
+
+ # Check length of _maxes and _lists match.
+
+ assert len(self._maxes) == len(self._lists) == len(self._keys)
+
+ # Check _keys matches _key mapped to _lists.
+
+ assert all(len(val_list) == len(key_list)
+ for val_list, key_list in zip(self._lists, self._keys))
+ assert all(self._key(val) == key for val, key in
+ zip((_val for _val_list in self._lists for _val in _val_list),
+ (_key for _key_list in self._keys for _key in _key_list)))
+
+ # Check _maxes is a map of _keys.
+
+ assert all(self._maxes[pos] == self._keys[pos][-1]
+ for pos in range(len(self._maxes)))
+
+ # Check load level is less than _twice.
+
+ assert all(len(sublist) <= self._twice for sublist in self._lists)
+
+ # Check load level is greater than _half for all
+ # but the last sublist.
+
+ assert all(len(self._lists[pos]) >= self._half
+ for pos in range(0, len(self._lists) - 1))
+
+ # Check length.
+
+ assert self._len == sum(len(sublist) for sublist in self._lists)
+
+ # Check index.
+
+ if len(self._index):
+ assert len(self._index) == self._offset + len(self._lists)
+ assert self._len == self._index[0]
+
+ def test_offset_pos(pos):
+ from_index = self._index[self._offset + pos]
+ return from_index == len(self._lists[pos])
+
+ assert all(test_offset_pos(pos)
+ for pos in range(len(self._lists)))
+
+ for pos in range(self._offset):
+ child = (pos << 1) + 1
+ if self._index[pos] == 0:
+ assert child >= len(self._index)
+ elif child + 1 == len(self._index):
+ assert self._index[pos] == self._index[child]
+ else:
+ child_sum = self._index[child] + self._index[child + 1]
+ assert self._index[pos] == child_sum
+
+ except:
+ import sys
+ import traceback
+
+ traceback.print_exc(file=sys.stdout)
+
+ print('len', self._len)
+ print('load', self._load, self._half, self._twice)
+ print('offset', self._offset)
+ print('len_index', len(self._index))
+ print('index', self._index)
+ print('len_maxes', len(self._maxes))
+ print('maxes', self._maxes)
+ print('len_keys', len(self._keys))
+ print('keys', self._keys)
+ print('len_lists', len(self._lists))
+ print('lists', self._lists)
+
+ raise
diff --git a/src/sortedcontainers/sortedset.py b/src/sortedcontainers/sortedset.py
new file mode 100755
index 0000000..d9ab42c
--- /dev/null
+++ b/src/sortedcontainers/sortedset.py
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted set implementation.
+
+from .sortedlist import SortedList, recursive_repr
+from .sortedlistwithkey import SortedListWithKey
+from collections import Set, MutableSet, Sequence
+from itertools import chain
+import operator as op
+
+class SortedSet(MutableSet, Sequence):
+ """
+ A `SortedSet` provides the same methods as a `set`. Additionally, a
+ `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
+ be indexed.
+
+ Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
+ """
+ def __init__(self, iterable=None, key=None, load=1000, _set=None):
+ """
+ A `SortedSet` provides the same methods as a `set`. Additionally, a
+ `SortedSet` maintains its items in sorted order, allowing the
+ `SortedSet` to be indexed.
+
+ An optional *iterable* provides an initial series of items to populate
+ the `SortedSet`.
+
+ An optional *key* argument defines a callable that, like the `key`
+ argument to Python's `sorted` function, extracts a comparison key from
+ each set item. If no function is specified, the default compares the
+ set items directly.
+
+ An optional *load* specifies the load-factor of the set. The default
+ load factor of '1000' works well for sets from tens to tens of millions
+ of elements. Good practice is to use a value that is the cube root of
+ the set size. With billions of elements, the best load factor depends
+ on your usage. It's best to leave the load factor at the default until
+ you start benchmarking.
+ """
+ self._key = key
+ self._load = load
+
+ self._set = set() if _set is None else _set
+
+ _set = self._set
+ self.isdisjoint = _set.isdisjoint
+ self.issubset = _set.issubset
+ self.issuperset = _set.issuperset
+
+ if key is None:
+ self._list = SortedList(self._set, load=load)
+ else:
+ self._list = SortedListWithKey(self._set, key=key, load=load)
+
+ _list = self._list
+ self.bisect_left = _list.bisect_left
+ self.bisect = _list.bisect
+ self.bisect_right = _list.bisect_right
+ self.index = _list.index
+
+ if iterable is not None:
+ self.update(iterable)
+
+ def __contains__(self, value):
+ """Return True if and only if *value* is an element in the set."""
+ return (value in self._set)
+
+ def __getitem__(self, index):
+ """
+ Return the element at position *index*.
+
+ Supports slice notation and negative indexes.
+ """
+ return self._list[index]
+
+ def __delitem__(self, index):
+ """
+ Remove the element at position *index*.
+
+ Supports slice notation and negative indexes.
+ """
+ _list = self._list
+ if isinstance(index, slice):
+ values = _list[index]
+ self._set.difference_update(values)
+ else:
+ value = _list[index]
+ self._set.remove(value)
+ del _list[index]
+
+ def _make_cmp(set_op, doc):
+ def comparer(self, that):
+ if isinstance(that, SortedSet):
+ return set_op(self._set, that._set)
+ elif isinstance(that, Set):
+ return set_op(self._set, that)
+ else:
+ raise TypeError('can only compare to a Set')
+
+ comparer.__name__ = '__{0}__'.format(set_op.__name__)
+ comparer.__doc__ = 'Return True if and only if ' + doc
+
+ return comparer
+
+ __eq__ = _make_cmp(op.eq, 'self and *that* are equal sets.')
+ __ne__ = _make_cmp(op.ne, 'self and *that* are inequal sets.')
+ __lt__ = _make_cmp(op.lt, 'self is a proper subset of *that*.')
+ __gt__ = _make_cmp(op.gt, 'self is a proper superset of *that*.')
+ __le__ = _make_cmp(op.le, 'self is a subset of *that*.')
+ __ge__ = _make_cmp(op.ge, 'self is a superset of *that*.')
+
+ def __len__(self):
+ """Return the number of elements in the set."""
+ return len(self._set)
+
+ def __iter__(self):
+ """
+ Return an iterator over the SortedSet. Elements are iterated over
+ in their sorted order.
+ """
+ return iter(self._list)
+
+ def __reversed__(self):
+ """
+ Return an iterator over the SortedSet. Elements are iterated over
+ in their reversed sorted order.
+ """
+ return reversed(self._list)
+
+ def add(self, value):
+ """Add the element *value* to the set."""
+ if value not in self._set:
+ self._set.add(value)
+ self._list.add(value)
+
+ def clear(self):
+ """Remove all elements from the set."""
+ self._set.clear()
+ self._list.clear()
+
+ def copy(self):
+ """Create a shallow copy of the sorted set."""
+ return self.__class__(key=self._key, load=self._load, _set=set(self._set))
+
+ __copy__ = copy
+
+ def count(self, value):
+ """Return the number of occurrences of *value* in the set."""
+ return 1 if value in self._set else 0
+
+ def discard(self, value):
+ """
+ Remove the first occurrence of *value*. If *value* is not a member,
+ does nothing.
+ """
+ if value in self._set:
+ self._set.remove(value)
+ self._list.discard(value)
+
+ def pop(self, index=-1):
+ """
+ Remove and return item at *index* (default last). Raises IndexError if
+ set is empty or index is out of range. Negative indexes are supported,
+ as for slice indices.
+ """
+ value = self._list.pop(index)
+ self._set.remove(value)
+ return value
+
+ def remove(self, value):
+ """
+ Remove first occurrence of *value*. Raises ValueError if
+ *value* is not present.
+ """
+ self._set.remove(value)
+ self._list.remove(value)
+
+ def difference(self, *iterables):
+ """
+ Return a new set with elements in the set that are not in the
+ *iterables*.
+ """
+ diff = self._set.difference(*iterables)
+ new_set = self.__class__(key=self._key, load=self._load, _set=diff)
+ return new_set
+
+ __sub__ = difference
+ __rsub__ = __sub__
+
+ def difference_update(self, *iterables):
+ """
+ Update the set, removing elements found in keeping only elements
+ found in any of the *iterables*.
+ """
+ values = set(chain(*iterables))
+ if (4 * len(values)) > len(self):
+ self._set.difference_update(values)
+ self._list.clear()
+ self._list.update(self._set)
+ else:
+ _discard = self.discard
+ for value in values:
+ _discard(value)
+ return self
+
+ __isub__ = difference_update
+
+ def intersection(self, *iterables):
+ """
+ Return a new set with elements common to the set and all *iterables*.
+ """
+ comb = self._set.intersection(*iterables)
+ new_set = self.__class__(key=self._key, load=self._load, _set=comb)
+ return new_set
+
+ __and__ = intersection
+ __rand__ = __and__
+
+ def intersection_update(self, *iterables):
+ """
+ Update the set, keeping only elements found in it and all *iterables*.
+ """
+ self._set.intersection_update(*iterables)
+ self._list.clear()
+ self._list.update(self._set)
+ return self
+
+ __iand__ = intersection_update
+
+ def symmetric_difference(self, that):
+ """
+ Return a new set with elements in either *self* or *that* but not both.
+ """
+ diff = self._set.symmetric_difference(that)
+ new_set = self.__class__(key=self._key, load=self._load, _set=diff)
+ return new_set
+
+ __xor__ = symmetric_difference
+ __rxor__ = __xor__
+
+ def symmetric_difference_update(self, that):
+ """
+ Update the set, keeping only elements found in either *self* or *that*,
+ but not in both.
+ """
+ self._set.symmetric_difference_update(that)
+ self._list.clear()
+ self._list.update(self._set)
+ return self
+
+ __ixor__ = symmetric_difference_update
+
+ def union(self, *iterables):
+ """
+ Return a new SortedSet with elements from the set and all *iterables*.
+ """
+ return self.__class__(chain(iter(self), *iterables), key=self._key, load=self._load)
+
+ __or__ = union
+ __ror__ = __or__
+
+ def update(self, *iterables):
+ """Update the set, adding elements from all *iterables*."""
+ values = set(chain(*iterables))
+ if (4 * len(values)) > len(self):
+ self._set.update(values)
+ self._list.clear()
+ self._list.update(self._set)
+ else:
+ _add = self.add
+ for value in values:
+ _add(value)
+ return self
+
+ __ior__ = union
+
+ def __reduce__(self):
+ return (self.__class__, ((), self._key, self._load, self._set))
+
+ @recursive_repr
+ def __repr__(self):
+ temp = '{0}({1}, key={2}, load={3})'
+ return temp.format(
+ self.__class__.__name__,
+ repr(list(self)),
+ repr(self._key),
+ repr(self._load)
+ )
+
+ def _check(self):
+ self._list._check()
+ assert len(self._set) == len(self._list)
+ _set = self._set
+ assert all(val in _set for val in self._list)
diff --git a/src/tophat-fusion-post b/src/tophat-fusion-post
index 64fb53d..f055ee9 100755
--- a/src/tophat-fusion-post
+++ b/src/tophat-fusion-post
@@ -2865,7 +2865,7 @@ def prog_path(program):
def get_version():
- return "2.1.0"
+ return "2.1.1"
def main(argv=None):
diff --git a/src/tophat.py b/src/tophat.py
index 66eb89e..1eed276 100755
--- a/src/tophat.py
+++ b/src/tophat.py
@@ -1288,9 +1288,21 @@ def check_bowtie_index(idx_prefix, is_bowtie2, add="(genome)"):
os.path.exists(idx_rev_2):
if os.path.exists(idx_prefix + ".1.ebwt") and os.path.exists(idx_prefix + ".1.bt2"):
print >> sys.stderr, bwtbotherr
-
return
else:
+ if is_bowtie2:
+ idxext="bt2l"
+ bowtie_ver="2 "
+ idx_fwd_1 = idx_prefix + ".1."+idxext
+ idx_fwd_2 = idx_prefix + ".2."+idxext
+ idx_rev_1 = idx_prefix + ".rev.1."+idxext
+ idx_rev_2 = idx_prefix + ".rev.2."+idxext
+ if os.path.exists(idx_fwd_1) and \
+ os.path.exists(idx_fwd_2) and \
+ os.path.exists(idx_rev_1) and \
+ os.path.exists(idx_rev_2):
+ return
+
bwtidxerr="Error: Could not find Bowtie "+bowtie_ver+"index files (" + idx_prefix + ".*."+idxext+")"
if is_bowtie2:
@@ -4087,7 +4099,7 @@ def main(argv=None):
except Usage, err:
th_logp(sys.argv[0].split("/")[-1] + ": " + str(err.msg))
- th_logp(" for detailed help see http://tophat.cbcb.umd.edu/manual.html")
+ th_logp(" for detailed help see http://ccb.jhu.edu/software/tophat/manual.shtml")
return 2
diff --git a/src/tophat2.in b/src/tophat2.in
deleted file mode 100644
index d4f66c3..0000000
--- a/src/tophat2.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-prefix="__PREFIX__"
-pbin=""
-if [[ -z $prefix ]]; then
- fl=$(readlink $0)
- if [[ -z $fl ]]; then
- pbin=$(dirname $0)
- else
- pbin=$(dirname $fl)
- fi
-else
- pbin=$prefix/bin
-fi
-export PATH=$pbin:$PATH
-$pbin/tophat "$@"
diff --git a/src/tophat2.sh b/src/tophat2.sh
new file mode 100644
index 0000000..4ab88ee
--- /dev/null
+++ b/src/tophat2.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+pbin=""
+fl=$(readlink $0)
+if [[ -z "$fl" ]]; then
+ pbin=$(dirname $0)
+ else
+ pbin=$(dirname $fl)
+fi
+export PATH=$pbin:$PATH
+$pbin/tophat "$@"
diff --git a/src/tophat_reports.cpp b/src/tophat_reports.cpp
index 99dddd0..50d2165 100644
--- a/src/tophat_reports.cpp
+++ b/src/tophat_reports.cpp
@@ -16,6 +16,9 @@
#include <cassert>
#include <cstdio>
+#include <boost/thread.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
#include <cstring>
#include <vector>
#include <string>
@@ -30,8 +33,6 @@
#include <seqan/file.h>
#include <getopt.h>
#include <inttypes.h>
-#include <boost/thread.hpp>
-#include <boost/random/mersenne_twister.hpp>
#include "common.h"
#include "utils.h"
@@ -709,7 +710,7 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
string qname(read_alt_name);
size_t slash_pos=qname.rfind('/');
- if (slash_pos!=string::npos)
+ if (slash_pos!=string::npos && qname.length()-slash_pos<4)
qname.resize(slash_pos);
//read_alt_name as QNAME
int flag=atoi(sam_toks[1].c_str()); //FLAG
@@ -798,19 +799,19 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
tokenize(bwt_buf, "\t", sam_toks);
string qname(read_alt_name);
size_t slash_pos=qname.rfind('/');
- if (slash_pos!=string::npos)
+ if (slash_pos!=string::npos && qname.length()-slash_pos<4)
qname.resize(slash_pos);
//read_alt_name as QNAME
int flag = atoi(sam_toks[1].c_str());
// 0x0010 (strand of query) is assumed to be set correctly
// to begin with
- flag |= 0x0001; //it must be paired
+ flag |= BAM_FPAIRED; //it must be paired
if (insert_side == FRAG_LEFT)
- flag |= 0x0040;
+ flag |= BAM_FREAD1;
else if (insert_side == FRAG_RIGHT)
- flag |= 0x0080;
+ flag |= BAM_FREAD2;
if (!primary)
- flag |= 0x100;
+ flag |= BAM_FSECONDARY;
string ref_name = sam_toks[2], ref_name2 = "";
char cigar1[1024] = {0}, cigar2[1024] = {0};
@@ -878,9 +879,9 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
}
mate_pos = partner->left() + 1;
if (grade.happy())
- flag |= 0x0002;
+ flag |= BAM_FPROPER_PAIR;
if (partner->antisense_align())
- flag |= 0x0020;
+ flag |= BAM_FMREVERSE;
if (fusion_alignment)
{
@@ -914,7 +915,7 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
}
else {
mate_pos = 0;
- flag |= 0x0008;
+ flag |= BAM_FMUNMAP;
}
string rg_aux = "";
@@ -2289,12 +2290,12 @@ struct ReportWorker {
char map_flags=read_best_alignments(curr_hit_group, best_hits, *gtf_junctions, *junctions,
*insertions, *deletions, *fusions, *coverage, final_report, &rng);
- char map_code=0;
+ //char map_code=0;
if (map_flags & 4) {
(*aligned_counter_multi)++;
}
if (map_flags & 16) {
- map_code='M';
+ //map_code='M';
(*aligned_counter_xmulti)++;
}
if (map_flags & 1) (*aligned_counter)++; //acceptable mappings found
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/tophat.git
More information about the debian-med-commit
mailing list