[med-svn] [axe-demultiplexer] 01/07: Imported Upstream version 0.2.7
Kevin Murray
daube-guest at moszumanska.debian.org
Thu Jul 30 11:14:25 UTC 2015
This is an automated email from the git hooks/post-receive script.
daube-guest pushed a commit to branch master
in repository axe-demultiplexer.
commit 41c798a3cb7f2d2f663e3d0e220c9dabe6992b57
Author: Kevin Murray <spam at kdmurray.id.au>
Date: Thu Jul 30 20:46:51 2015 +1000
Imported Upstream version 0.2.7
---
.gitignore | 12 +
.travis.yml | 39 +
CMakeLists.txt | 76 +
LICENSE.txt | 619 +++
README.md | 134 +
TODO.md | 9 +
cmake-modules/FindGSL.cmake | 130 +
cmake-modules/FindLIBQES.cmake | 83 +
docs/.gitignore | 1 +
docs/CMakeLists.txt | 24 +
docs/Makefile | 177 +
docs/algorithm.rst | 68 +
docs/conf.py | 332 ++
docs/index.rst | 29 +
docs/usage.rst | 108 +
docs/usage.txt | 24 +
src/CMakeLists.txt | 13 +
src/axe.c | 1622 ++++++++
src/axe.h | 283 ++
src/axe_config.h.in | 22 +
src/datrie/alpha-map-private.h | 52 +
src/datrie/alpha-map.c | 377 ++
src/datrie/alpha-map.h | 90 +
src/datrie/darray.c | 757 ++++
src/datrie/darray.h | 109 +
src/datrie/dstring-private.h | 45 +
src/datrie/dstring.c | 189 +
src/datrie/dstring.h | 62 +
src/datrie/tail.c | 388 ++
src/datrie/tail.h | 96 +
src/datrie/trie-private.h | 50 +
src/datrie/trie-string.c | 114 +
src/datrie/trie-string.h | 65 +
src/datrie/trie.c | 958 +++++
src/datrie/trie.h | 220 ++
src/datrie/triedefs.h | 85 +
src/datrie/typedefs.h | 43 +
src/gsl/combination.c | 171 +
src/gsl/error.c | 77 +
src/gsl/gsl_combination.h | 76 +
src/gsl/gsl_errno.h | 153 +
src/gsl/gsl_message.h | 79 +
src/gsl/init.c | 127 +
src/gsl/message.c | 37 +
src/gsl/stream.c | 65 +
src/gsl/strerror.c | 100 +
src/libqes/.gitignore | 12 +
src/libqes/.travis.yml | 38 +
src/libqes/AUTHORS | 1 +
src/libqes/CMakeLists.txt | 154 +
src/libqes/LICENSE | 619 +++
src/libqes/README.md | 31 +
src/libqes/cmake-modules/CodeCoverage.cmake | 158 +
src/libqes/cmake-modules/FindLIBQES.cmake | 83 +
.../cmake-modules/GetGitRevisionDescription.cmake | 130 +
.../GetGitRevisionDescription.cmake.in | 38 +
src/libqes/cmake-modules/GitSemVer.cmake | 27 +
src/libqes/src/CMakeLists.txt | 16 +
src/libqes/src/crc.c | 101 +
src/libqes/src/crc.h | 46 +
src/libqes/src/qes.h | 26 +
src/libqes/src/qes_compat.c | 66 +
src/libqes/src/qes_compat.h | 29 +
src/libqes/src/qes_config.h.in | 76 +
src/libqes/src/qes_file.c | 496 +++
src/libqes/src/qes_file.h | 213 +
src/libqes/src/qes_libgnu.c | 16 +
src/libqes/src/qes_libgnu.h | 28 +
src/libqes/src/qes_log.c | 251 ++
src/libqes/src/qes_log.h | 150 +
src/libqes/src/qes_match.c | 83 +
src/libqes/src/qes_match.h | 50 +
src/libqes/src/qes_seq.c | 157 +
src/libqes/src/qes_seq.h | 187 +
src/libqes/src/qes_seqfile.c | 319 ++
src/libqes/src/qes_seqfile.h | 224 ++
src/libqes/src/qes_sequtil.c | 256 ++
src/libqes/src/qes_sequtil.h | 23 +
src/libqes/src/qes_str.c | 36 +
src/libqes/src/qes_str.h | 135 +
src/libqes/src/qes_util.c | 59 +
src/libqes/src/qes_util.h | 236 ++
src/libqes/test/CMakeLists.txt | 36 +
src/libqes/test/benchmarks.c | 295 ++
src/libqes/test/data/bad_diff_lens.fastq | 4 +
src/libqes/test/data/bad_nohdr.fastq | 3 +
src/libqes/test/data/bad_noqual.fastq | 3 +
src/libqes/test/data/bad_noqualhdrchr.fastq | 4 +
src/libqes/test/data/bad_noqualhdreol.fastq | 3 +
src/libqes/test/data/empty.fastq | 1 +
src/libqes/test/data/empty.txt | 0
src/libqes/test/data/log_test.txt | 2 +
src/libqes/test/data/loremipsum.txt | 11 +
src/libqes/test/data/loremipsum.txt.gz | Bin 0 -> 427 bytes
src/libqes/test/data/nocomment.fasta | 5 +
src/libqes/test/data/random.bin | Bin 0 -> 8192 bytes
src/libqes/test/data/test.fasta | 4061 ++++++++++++++++++++
src/libqes/test/data/test.fastq | 4000 +++++++++++++++++++
src/libqes/test/data/test.fastq.bz2 | Bin 0 -> 17766 bytes
src/libqes/test/data/test.fastq.gz | Bin 0 -> 24811 bytes
src/libqes/test/helpers.c | 191 +
src/libqes/test/helpers.h | 40 +
src/libqes/test/kseq.h | 235 ++
src/libqes/test/logdemo.c | 34 +
src/libqes/test/test.c | 64 +
src/libqes/test/test_file.c | 430 +++
src/libqes/test/test_helpers.c | 54 +
src/libqes/test/test_log.c | 173 +
src/libqes/test/test_match.c | 89 +
src/libqes/test/test_seq.c | 422 ++
src/libqes/test/test_seqfile.c | 402 ++
src/libqes/test/test_sequtil.c | 51 +
src/libqes/test/test_util.c | 145 +
src/libqes/test/testdata.c | 144 +
src/libqes/test/testdata.h | 49 +
src/libqes/test/tests.h | 57 +
src/libqes/test/tinytest/tinytest.c | 493 +++
src/libqes/test/tinytest/tinytest.h | 100 +
src/libqes/test/tinytest/tinytest_macros.h | 199 +
src/libqes/util/make_codon_list.py | 38 +
src/libqes/util/make_codon_map.py | 21 +
src/main.c | 409 ++
tests/CMakeLists.txt | 91 +
tests/axe_integration.py | 201 +
tests/data/fake.barcodes | 3 +
tests/data/fake_0mm_R1.fq.gz | Bin 0 -> 240 bytes
tests/data/fake_1mm_R1.fq.gz | Bin 0 -> 241 bytes
tests/data/fake_2mm_R1.fq.gz | Bin 0 -> 241 bytes
tests/data/gbs.barcodes | 97 +
tests/data/gbs_R1.fastq.gz | Bin 0 -> 88880 bytes
tests/data/gbs_R2.fastq.gz | Bin 0 -> 87087 bytes
tests/data/gbs_se.barcodes | 97 +
tests/data/pare.barcodes | 10 +
tests/data/pare.fq.gz | Bin 0 -> 374 bytes
tests/data/pare_full.fq.gz | Bin 0 -> 247 bytes
tests/test.c | 60 +
tests/test_libaxe.c | 95 +
tests/tests.h | 47 +
utils/make-tarball.sh | 18 +
139 files changed, 25947 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b383896
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+# Editor temp files
+*.swp
+*.bak
+*~
+
+# compiled
+build
+*.o
+*.a
+*.so
+tags
+version
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..cb215e3
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,39 @@
+language: c
+
+env:
+ matrix:
+ - BUILD_TYPE=Release
+ - BUILD_TYPE=Debug
+
+compiler:
+ - clang
+ - gcc
+
+before_install:
+ - sudo add-apt-repository --yes ppa:kalakris/cmake
+ - sudo apt-get update -qq
+ - sudo apt-get install --yes cmake
+ - sudo apt-get update
+ - sudo apt-get install lcov python-pip valgrind libgsl0-dev
+ - mkdir zlib && cd zlib
+ - wget http://zlib.net/zlib-1.2.8.tar.gz
+ - tar xvxf zlib-1.2.8.tar.gz
+ - cd zlib-1.2.8
+ - ./configure
+ - make
+ - sudo make install
+ - cd ../..
+
+install:
+ - git submodule update --init
+ - mkdir build
+ - mkdir target
+ - cd build
+
+script:
+ - cmake .. -DCMAKE_INSTALL_PREFIX=../target -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+ - make
+ - python ../tests/axe_integration.py .
+ - ./bin/test_axe
+ - make install
+ - test -f ../target/bin/axe
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..75fd536
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,76 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(axe C)
+
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-modules")
+
+# Cmake options
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+ENABLE_TESTING()
+
+IF (NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Release)
+ENDIF()
+
+IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version")
+ FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/version" AXE_VERSION)
+ELSE()
+ # git describe as versioning
+ EXECUTE_PROCESS(COMMAND git describe
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE AXE_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF()
+
+MESSAGE(STATUS "${CMAKE_BUILD_TYPE} build of axe version: ${AXE_VERSION}")
+
+###############################
+## Find Packages and Headers ##
+###############################
+
+# Done by libqes' CML.txt
+
+##########################
+## Set Compiler Options ##
+##########################
+
+IF (CMAKE_COMPILER_IS_GNUCC)
+ SET(AXEWRN "${AXEWRN} -Woverride-init -Wnormalized=id -Wlogical-op")
+ EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+ OUTPUT_VARIABLE GCC_VERSION)
+ IF (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
+ ENDIF()
+ENDIF()
+
+# Set CFLAGS
+SET(AXEWRN "${AXEWRN} -fstack-protector-all -Wstack-protector -Wfloat-equal")
+SET(AXEWRN "${AXEWRN} -Wundef -Wpointer-arith -Wstrict-prototypes")
+SET(AXEWRN "${AXEWRN} -Wmissing-prototypes -Wwrite-strings -Wredundant-decls")
+SET(AXEWRN "${AXEWRN} -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings")
+SET(AXEWRN "${AXEWRN} -Wmissing-declarations -Wredundant-decls -Wnested-externs")
+SET(AXEWRN "${AXEWRN} -Wbad-function-cast -Wswitch-enum -Winit-self")
+SET(AXEWRN "${AXEWRN} -Wmissing-field-initializers -Wdeclaration-after-statement")
+SET(AXEWRN "${AXEWRN} -Wold-style-definition -Waddress -Wmissing-noreturn ")
+SET(AXEWRN "${AXEWRN} -Wstrict-overflow=1 -Wextra -Warray-bounds -Wall -D_FORTIFY_SOURCE=2")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${AXEWRN}")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src
+ ${CMAKE_SOURCE_DIR}/src/datrie
+ ${CMAKE_SOURCE_DIR}/src/libqes/src
+ ${CMAKE_SOURCE_DIR}/src/gsl)
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lib)
+
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/src/axe_config.h.in
+ ${CMAKE_BINARY_DIR}/axe_config.h)
+
+ADD_SUBDIRECTORY(docs)
+ADD_SUBDIRECTORY(tests)
+ADD_SUBDIRECTORY(src)
+SET(LIBQES_AS_SUBMODULE True) # stop libqes installing itself
+ADD_SUBDIRECTORY(src/libqes)
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..bc08fe2
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,619 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5a18c3c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,134 @@
+AXE
+===
+
+> De-multiplex NGS reads using trie data structures. It's fast, and made of tries!
+
+[![DOI](https://zenodo.org/badge/6357/kdmurray91/axe.png)](https://zenodo.org/record/12278)
+[![Documentation Status](https://readthedocs.org/projects/axe-demultiplexer/badge/?version=latest)](https://readthedocs.org/projects/axe-demultiplexer/?badge=latest)
+
+
+AXE very rapidly selects the optimal barcode present in a sequence read, even
+in the presence of sequencing errors. The algorithm is able to handle
+combinatorial barcoding, barcodes of differing length, and several mismatches
+per barcode. Early results indicate far improved accuracy and speed over
+existing de-multiplexers. Unscientific trials show AXE processes more than
+500,000 reads per second.
+
+**Warning**: Axe has not yet been comprehensively tested. However, in the
+spirit of "release early and often", here it is.
+
+###Tests:
+
+| Jenkins GNU/Linux | [![Build Status](http://biojenkins.anu.edu.au/job/axe/badge/icon)](http://biojenkins.anu.edu.au/job/axe/) |
+| ----------------- | --- |
+| Jenkins MinGW | [![Build Status](http://biojenkins.anu.edu.au/job/axe-mingw/badge/icon)](http://biojenkins.anu.edu.au/job/axe-mingw/) |
+| TravisCI | [![Build Status](https://travis-ci.org/kdmurray91/axe.svg?branch=dev)](https://travis-ci.org/kdmurray91/axe) |
+| Test Coverage | [![Coverage Status](https://img.shields.io/coveralls/kdmurray91/axe.svg)](https://coveralls.io/r/kdmurray91/axe?branch=master) |
+| Coverity Scans | [![Coverity Scan Build Status](https://scan.coverity.com/projects/2666/badge.svg)](https://scan.coverity.com/projects/2666) |
+
+
+Installation:
+-------------
+
+Currently, only recent GNU/Linux systems are officially supported. All code and
+the build system is portable, so compilation and use on other systems should be
+possible, I just don't have machines available to test. Please report any
+installation issues on any system as GitHub bugs and I'll do my best to sort
+them out.
+
+In short, on *NIX, get the dependencies (see below), and:
+
+ git clone --recursive https://github.com/kdmurray91/axe.git axe
+ cd axe
+ mkdir -p build && cd build
+ cmake ..
+ make
+ sudo make install
+
+To install to a prefix, as you would with `./configure --prefix` with the
+autotools build system, please use the following cmake command in place of the
+one above:
+
+ cmake -DCMAKE_INSTALL_PREFIX=/path/to/your/prefix ..
+
+e.g.:
+
+ cmake -DCMAKE_INSTALL_PREFIX=$HOME ..
+
+For me, using `~/` as the prefix will install `axe` under `/home/kevin/bin` on
+GNU/Linux, and (if I had one) `/Users/kevin/bin` on Mac OSX.It's also wise to
+use `make install` not `sudo make install` when installing to a home directory.
+
+###Dependencies:
+
+- cmake. This is installable via `sudo apt-get install cmake` on Debian based
+ systems, or `brew install cmake` using homebrew on OS X.
+- zlib version >= 1.2.5. On Debian, use the package `zlib1g-dev`.
+- libqes, tinytest, libgsl and libdatrie (bundled in source, if you used
+ `git clone --recursive` or an installation tarball. Otherwise, run
+ `git submodule update --init`).
+
+You'll possibly need to install zlib to your chosen prefix (e.g. `~/`) on
+supercomputers, which often have very old versions of zlib. To do so:
+
+ wget http://zlib.net/zlib-1.2.8.tar.gz
+ tar xvf zlib-1.2.8.tar.gz
+ cd zlib-1.2.8
+ ./configure --prefix=<your_prefix> # e.g. --prefix=$HOME
+ make && make install
+
+And then, use the following cmake command, assuming your prefix is `~/`:
+
+ cmake -DCMAKE_INSTALL_PREFIX=$HOME -DZLIB_ROOT=$HOME ..
+
+
+Usage:
+------
+
+Full documentation, including a basic description of the algorithm, is hosted
+at https://axe-demultiplexer.readthedocs.org/en/latest/ .
+
+
+Implementation Progress:
+------------------------
+
+ - [x] Single ended read de-multiplexing
+ - [x] Interleaved/Paired input and output with single-ended de-multiplexing
+ - [x] Combinatorial de-multiplexing
+ - [ ] CLI integration tests
+ - [ ] Comprehensive `libaxe` tests
+ - [ ] Comprehensive CLI tests
+
+See also TODO.md
+
+
+Publication
+-----------
+
+A publication is coming soon, if the reviewer gods decide to smile upon us.
+
+Versioning
+----------
+
+We use Semantic Versioning. See [semver.org](http://semver.org)
+
+LICENSE
+-------
+
+The source of axe itself, namely `src/axe*.[ch]` and `tests/*.[ch]`, is
+Copyright 2014-2015 Kevin Murray. All axe source code is licensed under the GNU
+GPL version 3 or greater, a copy of which is included with this source as
+`LICENCE.txt`
+
+The source of `tinytest`, located in `tests/tinytest`, is Copyright 2009-2012
+Nick Matthewson; `tinytest` is distributed under the 3-clause BSD license.
+`tinytest` is hosted at [Nick's github page](https://github.com/nmathewson/tinytest).
+
+The source of `libgsl`, located in `src/gsl`, is Copyright (C) 1996, 1997,
+1998, 1999, 2000, 2007 Gerard Jungman and Brian Gough. It is licensed under the
+GNU General Public License, vesion 3 or greater.
+
+The source of `libdatrie`, located in `src/datrie`, is Copyright 2006 Theppitak
+Karoonboonyanan, and is licensed under the GNU LGPL version 2.1 per
+`src/datrie/COPYING`. `libdatrie` is hosted at Theppitak Karoonboonyanan's
+website, [here](http://linux.thai.net/~thep/datrie/datrie.html).
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..ea035f0
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,9 @@
+TODO list:
+==========
+
+- Re-read documentation; fix errors
+- Exhaustive CLI tests
+- Refactor trie lookups to hide all datrie operations from main body of code
+- Summary info
+- Valgrind integration tests - maybe a CLI flag to enable
+- Investigate shipping the gsl functions bundled in source.
diff --git a/cmake-modules/FindGSL.cmake b/cmake-modules/FindGSL.cmake
new file mode 100644
index 0000000..0603f7d
--- /dev/null
+++ b/cmake-modules/FindGSL.cmake
@@ -0,0 +1,130 @@
+# Try to find gnu scientific library GSL
+# See
+# http://www.gnu.org/software/gsl/ and
+# http://gnuwin32.sourceforge.net/packages/gsl.htm
+#
+# Based on a script of Felix Woelk and Jan Woetzel
+# (www.mip.informatik.uni-kiel.de)
+#
+# It defines the following variables:
+# GSL_FOUND - system has GSL lib
+# GSL_INCLUDE_DIRS - where to find headers
+# GSL_LIBRARIES - full path to the libraries
+# GSL_LIBRARY_DIRS, the directory where the PLplot library is found.
+
+# CMAKE_GSL_CXX_FLAGS = Unix compiler flags for GSL, essentially "`gsl-config --cxxflags`"
+# GSL_LINK_DIRECTORIES = link directories, useful for rpath on Unix
+# GSL_EXE_LINKER_FLAGS = rpath on Unix
+
+set( GSL_FOUND OFF )
+set( GSL_CBLAS_FOUND OFF )
+
+# Windows, but not for Cygwin and MSys where gsl-config is available
+if( WIN32 AND NOT CYGWIN AND NOT MSYS )
+ # look for headers
+ find_path( GSL_INCLUDE_DIR
+ NAMES gsl/gsl_cdf.h gsl/gsl_randist.h
+ )
+ if( GSL_INCLUDE_DIR )
+ # look for gsl library
+ find_library( GSL_LIBRARY
+ NAMES gsl
+ )
+ if( GSL_LIBRARY )
+ set( GSL_INCLUDE_DIRS ${GSL_INCLUDE_DIR} )
+ get_filename_component( GSL_LIBRARY_DIRS ${GSL_LIBRARY} PATH )
+ set( GSL_FOUND ON )
+ endif( GSL_LIBRARY )
+
+ # look for gsl cblas library
+ find_library( GSL_CBLAS_LIBRARY
+ NAMES gslcblas
+ )
+ if( GSL_CBLAS_LIBRARY )
+ set( GSL_CBLAS_FOUND ON )
+ endif( GSL_CBLAS_LIBRARY )
+
+ set( GSL_LIBRARIES ${GSL_LIBRARY} ${GSL_CBLAS_LIBRARY} )
+ endif( GSL_INCLUDE_DIR )
+
+ mark_as_advanced(
+ GSL_INCLUDE_DIR
+ GSL_LIBRARY
+ GSL_CBLAS_LIBRARY
+ )
+else( WIN32 AND NOT CYGWIN AND NOT MSYS )
+ if( UNIX OR MSYS )
+ find_program( GSL_CONFIG_EXECUTABLE gsl-config
+ /usr/bin/
+ /usr/local/bin
+ )
+
+ if( GSL_CONFIG_EXECUTABLE )
+ set( GSL_FOUND ON )
+
+ # run the gsl-config program to get cxxflags
+ execute_process(
+ COMMAND sh "${GSL_CONFIG_EXECUTABLE}" --cflags
+ OUTPUT_VARIABLE GSL_CFLAGS
+ RESULT_VARIABLE RET
+ ERROR_QUIET
+ )
+ if( RET EQUAL 0 )
+ string( STRIP "${GSL_CFLAGS}" GSL_CFLAGS )
+ separate_arguments( GSL_CFLAGS )
+
+ # parse definitions from cflags; drop -D* from CFLAGS
+ string( REGEX MATCHALL "-D[^;]+"
+ GSL_DEFINITIONS "${GSL_CFLAGS}" )
+ string( REGEX REPLACE "-D[^;]+;" ""
+ GSL_CFLAGS "${GSL_CFLAGS}" )
+
+ # parse include dirs from cflags; drop -I prefix
+ string( REGEX MATCHALL "-I[^;]+"
+ GSL_INCLUDE_DIRS "${GSL_CFLAGS}" )
+ string( REPLACE "-I" ""
+ GSL_INCLUDE_DIRS "${GSL_INCLUDE_DIRS}")
+ string( REGEX REPLACE "-I[^;]+;" ""
+ GSL_CFLAGS "${GSL_CFLAGS}")
+ else( RET EQUAL 0 )
+ set( GSL_FOUND FALSE )
+ endif( RET EQUAL 0 )
+
+ # run the gsl-config program to get the libs
+ execute_process(
+ COMMAND sh "${GSL_CONFIG_EXECUTABLE}" --libs
+ OUTPUT_VARIABLE GSL_LIBRARIES
+ RESULT_VARIABLE RET
+ ERROR_QUIET
+ )
+ if( RET EQUAL 0 )
+ string(STRIP "${GSL_LIBRARIES}" GSL_LIBRARIES )
+ separate_arguments( GSL_LIBRARIES )
+
+ # extract linkdirs (-L) for rpath (i.e., LINK_DIRECTORIES)
+ string( REGEX MATCHALL "-L[^;]+"
+ GSL_LIBRARY_DIRS "${GSL_LIBRARIES}" )
+ string( REPLACE "-L" ""
+ GSL_LIBRARY_DIRS "${GSL_LIBRARY_DIRS}" )
+ else( RET EQUAL 0 )
+ set( GSL_FOUND FALSE )
+ endif( RET EQUAL 0 )
+
+ MARK_AS_ADVANCED(
+ GSL_CFLAGS
+ )
+ else( GSL_CONFIG_EXECUTABLE )
+ message( STATUS "FindGSL: gsl-config not found.")
+ endif( GSL_CONFIG_EXECUTABLE )
+ endif( UNIX OR MSYS )
+endif( WIN32 AND NOT CYGWIN AND NOT MSYS )
+
+if( GSL_FOUND )
+ if( NOT GSL_FIND_QUIETLY )
+ message( STATUS "FindGSL: Found both GSL headers and library" )
+ endif( NOT GSL_FIND_QUIETLY )
+else( GSL_FOUND )
+ if( GSL_FIND_REQUIRED )
+ message( FATAL_ERROR "FindGSL: Could not find GSL headers or library" )
+ endif( GSL_FIND_REQUIRED )
+endif( GSL_FOUND )
diff --git a/cmake-modules/FindLIBQES.cmake b/cmake-modules/FindLIBQES.cmake
new file mode 100644
index 0000000..295217c
--- /dev/null
+++ b/cmake-modules/FindLIBQES.cmake
@@ -0,0 +1,83 @@
+# - Find libqes
+# Find the native libqes includes and library.
+# Once done this will define
+#
+# LIBQES_INCLUDE_DIRS - where to find qes.h, etc.
+# LIBQES_LIBRARIES - List of libraries when using libqes.
+# LIBQES_FOUND - True if libqes found.
+#
+# LIBQES_VERSION_STRING - The version of libqes found (x.y.z)
+# LIBQES_VERSION_MAJOR - The major version of libqes
+# LIBQES_VERSION_MINOR - The minor version of libqes
+# LIBQES_VERSION_PATCH - The patch version of libqes
+# LIBQES_VERSION_PREREL - The pre-release version of libqes
+# LIBQES_VERSION_GIT - The git version of libqes
+#
+# An includer may set LIBQES_ROOT to a libqes installation root to tell
+# this module where to look.
+
+#=============================================================================
+# Copyright 2014 Kevin Murray. Adapted from FindZLIB.cmake
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+set(_LIBQES_SEARCHES)
+
+# Search LIBQES_ROOT first if it is set.
+if(LIBQES_ROOT)
+ set(_LIBQES_SEARCH_ROOT PATHS ${LIBQES_ROOT} NO_DEFAULT_PATH)
+ list(APPEND _LIBQES_SEARCHES _LIBQES_SEARCH_ROOT)
+endif()
+
+# Normal search.
+set(_LIBQES_SEARCH_NORMAL
+ PATHS "$ENV{PROGRAMFILES}/libqes"
+ )
+list(APPEND _LIBQES_SEARCHES _LIBQES_SEARCH_NORMAL)
+
+# Try each search configuration.
+foreach(search ${_LIBQES_SEARCHES})
+ find_path(LIBQES_INCLUDE_DIR NAMES qes.h ${${search}} PATH_SUFFIXES include)
+ find_library(LIBQES_LIBRARY NAMES qes ${${search}} PATH_SUFFIXES lib)
+endforeach()
+
+mark_as_advanced(LIBQES_LIBRARY LIBQES_INCLUDE_DIR)
+# Handle version. Again, flogged from zlib
+if(LIBQES_INCLUDE_DIR AND EXISTS "${LIBQES_INCLUDE_DIR}/qes_config.h")
+ file(STRINGS "${LIBQES_INCLUDE_DIR}/qes_config.h" LIBQES_H REGEX "^#define LIBQES_VERSION \"[^\"]*\"")
+
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?([0-9]+).*$" "\\1" LIBQES_VERSION_MAJOR "${LIBQES_H}")
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.([0-9]+).*$" "\\1" LIBQES_VERSION_MINOR "${LIBQES_H}")
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBQES_VERSION_PATCH "${LIBQES_H}")
+ set(LIBQES_VERSION_STRING "${LIBQES_VERSION_MAJOR}.${LIBQES_VERSION_MINOR}.${LIBQES_VERSION_PATCH}")
+
+ # only append a EXTRA version if it exists:
+ set(LIBQES_VERSION_EXTRA "")
+ if( "${LIBQES_H}" MATCHES "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.[0-9]+(.+)\\+git.*$")
+ set(LIBQES_VERSION_PREREL "${CMAKE_MATCH_1}")
+ endif()
+ if( "${LIBQES_H}" MATCHES "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.[0-9]+.*\\+git\\.(.+)$")
+ set(LIBQES_VERSION_git "${CMAKE_MATCH_1}")
+ endif()
+ set(LIBQES_VERSION_STRING "${LIBQES_VERSION_STRING}${LIBQES_VERSION_PREREL}")
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set LIBQES_FOUND to TRUE if
+# all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBQES REQUIRED_VARS LIBQES_LIBRARY LIBQES_INCLUDE_DIR
+ VERSION_VAR LIBQES_VERSION_STRING)
+
+if(LIBQES_FOUND)
+ set(LIBQES_INCLUDE_DIRS ${LIBQES_INCLUDE_DIR})
+ set(LIBQES_LIBRARIES ${LIBQES_LIBRARY})
+endif()
+
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..24e5b0a
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1 @@
+.build
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644
index 0000000..5d808f8
--- /dev/null
+++ b/docs/CMakeLists.txt
@@ -0,0 +1,24 @@
+FIND_PROGRAM(SPHINXBUILD sphinx-build)
+IF(SPHINXBUILD)
+ SET(ALLSPHINXOPTS -q -D latex_paper_size=a4)
+ ADD_CUSTOM_TARGET(doc_html
+ COMMAND ${SPHINXBUILD} -b html ${ALLSPHINXOPTS} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/doc/html
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ ADD_CUSTOM_TARGET(doc_onehtml
+ COMMAND ${SPHINXBUILD} -b singlehtml ${ALLSPHINXOPTS} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/doc/single
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ ADD_CUSTOM_TARGET(doc_man
+ COMMAND ${SPHINXBUILD} -b man ${ALLSPHINXOPTS} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/doc/man
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ ADD_CUSTOM_TARGET(doc_clean
+ COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/doc"
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ ADD_CUSTOM_TARGET(doc ALL DEPENDS doc_man doc_onehtml)
+ INSTALL(FILES ${CMAKE_BINARY_DIR}/doc/man/axe.1 DESTINATION "share/man/man1")
+ SET_DIRECTORY_PROPERTIES(PROPERTY ADDITIONAL_MAKE_CLEAN_FILES doc/)
+ENDIF()
+
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..06e01b3
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = .build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/axe.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/axe.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/axe"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/axe"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/algorithm.rst b/docs/algorithm.rst
new file mode 100644
index 0000000..865c4c6
--- /dev/null
+++ b/docs/algorithm.rst
@@ -0,0 +1,68 @@
+************************
+Axe's matching algorithm
+************************
+
+Axe uses an algorithm based on longest-prefix-in-trie matching to match a
+variable length from the start of each read against a set of 'mutated'
+barcodes.
+
+Hamming distance matching
+-------------------------
+
+While for most applications in high-throughput sequencing hamming distances are
+a frowned-upon metric, it is typical for HTS read barcodes to be designed to
+tolerate a certain level of hamming mismatches. Given these sequences are short
+and typically occur at the 5' end of reads, insertions and deletions rarely
+need be considered, and the increased rate of assignment of reads with many
+errors is offset by the risk of falsely assigning barcodes to an incorrect
+sample. In any case, reads with more than 1-2 sequencing errors in their first
+several bases are likely to be poor quality, and will simply be filtered out
+during downstream quality control.
+
+Hamming mismatch tries
+----------------------
+
+Typically, reads are matched to a set of barcodes by calculating the hamming
+distance between the barcode, and the first :math:`l` bases of a read for a
+barcode of length :math:`l`. The "correct" barcode is then selected by
+recording either the barcode with the lowest hamming distance to the read
+(competitive matching) or by simply accepting the first barcode with a hamming
+distance below a certain threshold. These approaches are both very
+computationally expensive, and can have lower accuracy than the algorithm I
+propose. Additionally, implementations of these methods rarely handle barcodes
+of differing length and combinatorial barcoding well, if at all.
+
+Central to Axe's algorithm is the concept of hamming-mismatch tries. A trie is
+a N-ary tree for an N letter alphabet. In the case of high-throughput
+sequencing reads, we have the alphabet ``AGCT``, corresponding to the four
+nucleotides of DNA, plus ``N``, used to represent ambiguous base calls. Instead
+of matching each barcode to each read, we pre-calculate all allowable sequences
+at each mismatch level, and store these in level-wise tries. For example, to
+match to a hamming distance of 2, we create three tries: One containing all
+barcodes, verbatim, and two tries where every sequence within a hamming
+distance of 1 and 2 of each barcode respectively. Hereafter, these tries are
+referred to as the 0, 1 and 2-mm tries, for a hamming distance (mismatch) of
+0, 1 and 2. Then, we find the longest prefix in each sequence read in the 0mm
+trie. If this prefix is not a valid leaf in the 0mm trie, we find the longest
+prefix in the 1mm trie, and so on for all tries in ascending order. If no
+prefix of the read is a complete sequence in any trie, the read is assigned to
+an "non-barcoded" output file.
+
+This algorithm ensures optimal barcode matching in many ways, but is also
+extremely fast. In situations with barcodes of differing length, we ensure that
+the *longest* acceptable barcode at a given hamming distance is chosen;
+assuming that sequence is random after the barcode, the probability of false
+assignments using this method is low. We also ensure that short perfect matches
+are preferred to longer inexact matches, as we firstly only consider barcodes
+with no error, then 1 error, and so on. This ensures that reads with barcodes
+that are followed by random sequence that happens to inexactly match a longer
+barcode in the set are not falsely assigned to this longer barcode.
+
+The speed of this algorithm is largely due to the constant time matching
+algorithm with respect to the number of barcodes to match. The time taken to
+match each read is proportional instead to the length of the barcodes, as for a
+barcode of length :math:`l`, at most :math:`l + 1` trie level descents are
+required to find an entry in the trie. As this length is more-or-less constant
+and small, the overall complexity of axe's algorithm is :math:`O(n)` for
+:math:`n` reads, as opposed to :math:`O(nm)` for :math:`n` reads and :math:`m`
+barcodes as is typical for traditional matching algorithms
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..b7aca36
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,332 @@
+# -*- coding: utf-8 -*-
+#
+# axe documentation build configuration file, created by
+# sphinx-quickstart on Fri Jul 25 09:16:47 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.todo',
+ 'sphinx.ext.pngmath',
+ 'sphinx.ext.ifconfig',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'axe'
+copyright = u'2014, Kevin Murray'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['.build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['.static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'axedoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+'papersize': 'a4paper',
+
+# The font size ('10pt', '11pt' or '12pt').
+'pointsize': '11pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'axe.tex', u'axe Documentation',
+ u'Kevin Murray', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'axe', u'axe Documentation',
+ [u'Kevin Murray'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'axe', u'axe Documentation',
+ u'Kevin Murray', 'axe', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+# -- Options for Epub output ----------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'axe'
+epub_author = u'Kevin Murray'
+epub_publisher = u'Kevin Murray'
+epub_copyright = u'2014, Kevin Murray'
+
+# The basename for the epub file. It defaults to the project name.
+#epub_basename = u'axe'
+
+# The HTML theme for the epub output. Since the default themes are not optimized
+# for small screen space, using the same theme for HTML and epub output is
+# usually not wise. This defaults to 'epub', a theme designed to save visual
+# space.
+#epub_theme = 'epub'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#epub_cover = ()
+
+# A sequence of (type, uri, title) tuples for the guide element of content.opf.
+#epub_guide = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
+
+# Choose between 'default' and 'includehidden'.
+#epub_tocscope = 'default'
+
+# Fix unsupported image types using the PIL.
+#epub_fix_images = False
+
+# Scale large images.
+#epub_max_image_width = 0
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#epub_show_urls = 'inline'
+
+# If false, no index is generated.
+#epub_use_index = True
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..480eac4
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,29 @@
+.. axe documentation master file, created by
+ sphinx-quickstart on Fri Jul 25 09:16:47 2014.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to axe's documentation!
+===============================
+
+Axe is a read de-multiplexer, useful in situations where sequence reads contain
+the barcodes that uniquely distinguish samples. Axe uses a rapid and accurate
+algorithm based on hamming mismatch tries to competitively match the prefix of
+a sequencing read against a set of barcodes. Axe supports combinatorial
+barcoding schemes.
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ usage
+ algorithm
+
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
diff --git a/docs/usage.rst b/docs/usage.rst
new file mode 100644
index 0000000..6eabfba
--- /dev/null
+++ b/docs/usage.rst
@@ -0,0 +1,108 @@
+*********
+Axe Usage
+*********
+
+Axe has several usage modes. The primary distinction is between the two
+alternate barcoding schemes, single and combinatorial barcoding. Single barcode
+matching is used when only the first read contains barcode sequences.
+Combinatorial barcoding is used when both reads in a read pair contain
+independent (typically different) barcode sequences.
+
+For concise reference, the command-line usage of ``axe`` is reproduced below:
+
+.. literalinclude:: usage.txt
+
+Inputs and Outputs
+------------------
+
+Regardless of read mode, three input and output schemes are supported:
+single-end reads, paired reads (separate R1 and R2 files) and interleaved
+paired reads (one file, with R1 and R2 as consecutive reads). If single end
+reads are inputted, they must be output as single end reads. If either paired or
+interleaved paired reads are read, they can be output as either paired reads or
+interleaved paired reads. This applies to both successfully de-multiplexed reads
+and reads that could not be de-multiplexed.
+
+The ``-z`` flag can be used to specify that outputs should be compressed using
+gzip compression. The ``-z`` flag takes an integer argument between 0 (the
+default) and 9, where 0 indicates plain text output (``gzopen`` mode "wT"), and
+1-9 indicate that the respective compression level should be used, where 1 is
+fastest and 9 is most compact.
+
+The output flags should be prefixes that are used to generate the output file
+name based on the barcode's (or barcode pair's) ID. The names are generated as:
+``prefix`` + ``_`` + ``barcode ID`` + ``_`` + ``read number`` + ``.extension``.
+The output file for reads that could not be demultiplexed is ``prefix`` + ``_``
++ ``unknown`` + ``_`` + ``read number`` + ``.extension``. The read number is
+omitted unless the paired read file scheme is used, and is "il" for interleaved
+output. The extension is "fastq"; ".gz" is appended to the extension if the
+``-z`` flag is used.
+
+The corresponding CLI flags are:
+ - ``-f`` and ``-F``: Single end or paired R1 file input and output
+ respectively.
+ - ``-r`` and ``-R``: Paired R2 file input and output.
+ - ``-i`` and ``-I``: Interleaved paired input and output.
+
+The barcode file
+----------------
+
+The barcode file is a tab-separated file with an optional header. It is
+mandatory, and is always supplied using the ``-b`` command line flag. The exact
+format is dependent on barcoding mode, and is described further in the sections
+below. If a header is present, the header line must start with either
+`Barcode` or ``barcode``, or it will be interpreted as a barcode line, leading
+to a parsing error. Any line starting with ';' or '#' is ignored, allowing
+comments to be added in line with barcodes. Please ensure that the software
+used to produce the barcode uses ASCII encoding, and does not insert a
+Byte-order Mark (BoM) as many text editors can silently use Unicode-based
+encoding schemes. I recommend the use of
+`LibreOffice Calc <www.libreoffice.org>`_ (part of a free and open source
+office suite) to generate barcode tables; Microsoft Excel can also be used.
+
+Mismatch level selection
+------------------------
+
+Independent of barcode mode, the ``-m`` flag is used to select the maximum
+allowable hamming distance between a read's prefix and a barcode to be
+considered as a match. As "mutated" barcodes must be unique, a hamming distance
+of one is the default as typically barcodes are designed to differ by a hamming
+distance of at least two. Optionally, (using the ``-p`` flag), axe will allow
+selective mismatch levels, where, if clashes are observed, the barcode will
+only be matched exactly. This allows one to process datasets with barcodes that
+don't have a sufficiently high distance between them.
+
+Single barcode mode
+-------------------
+
+Single barcode mode is the default mode of operation. Barcodes are matched
+against read one (hereafter the forward read), and the barcode is trimmed from
+only the forward read, unless the ``-2`` command line flag is given, in which
+case a prefix the same length as the matched barcode is also trimmed from the
+second or reverse read. Note that sequence of this second read is not checked
+before trimming.
+
+In single barcode mode, the barcode file has two columns: ``Barcode`` and
+``ID``.
+
+Combinatorial barcode mode
+--------------------------
+
+Combinatorial barcode mode is activated by giving the ``-c`` flag on the
+command line. Forward read barcodes are matched against the forward read, and
+reverse read barcodes are matched against the reverse read. The optimal
+barcodes are selected independently, and the barcode pair is selected from
+these two barcodes. The respective barcodes are trimmed from both reads; the
+``-2`` command line flag has no effect in combinatorial barcode mode.
+
+In combinatorial barcode mode, the barcode file has three columns:
+``Barcode1``, ``Barcode2`` and ``ID``. Individual barcodes can occur many times
+within the forward and reverse barcodes, but barcode pairs must be unique
+combinations.
+
+The Demultipexing Statistics File
+---------------------------------
+
+The ``-t`` option allows the output of per-sample read counts to a
+tab-separated file. The file will have a header describing its format, and
+includes a line for unbarcoded reads.
diff --git a/docs/usage.txt b/docs/usage.txt
new file mode 100644
index 0000000..31b52fe
--- /dev/null
+++ b/docs/usage.txt
@@ -0,0 +1,24 @@
+USAGE:
+axe [-mzc2pt] -b (-f [-r] | -i) (-F [-R] | -I)
+axe -h
+axe -v
+
+OPTIONS:
+ -m, --mismatch Maximum hamming distance mismatch. [int, default 1]
+ -z, --ziplevel Gzip compression level, or 0 for plain text [int, default 0]
+ -c, --combinatorial Use combinatorial barcode matching. [flag, default OFF]
+ -p, --permissive Don't error on barcode mismatch confict, matching only
+ exactly for conficting barcodes. [flag, default OFF]
+ -2, --trim-r2 Trim barcode from R2 read as well as R1. [flag, default OFF]
+ -b, --barcodes Barcode file. See --help for example. [file]
+ -f, --fwd-in Input forward read. [file]
+ -F, --fwd-out Output forward read prefix. [file]
+ -r, --rev-in Input reverse read. [file]
+ -R, --rev-out Output reverse read prefix. [file]
+ -i, --ilfq-in Input interleaved paired reads. [file]
+ -I, --ilfq-out Output interleaved paired reads prefix. [file]
+ -t, --table-file Output a summary table of demultiplexing statistics to file. [file]
+ -h, --help Print this usage plus additional help.
+ -V, --version Print version string.
+ -v, --verbose Be more verbose. Additive, -vv is more vebose than -v.
+ -q, --quiet Be very quiet.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..c94d70b
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Axe library (libaxe.a)
+FILE(GLOB DATRIE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/datrie/*.c)
+FILE(GLOB GSL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/gsl/*.c)
+SET(AXELIB_SRCS ${DATRIE_SRCS} ${GSL_SRCS} axe.c)
+
+ADD_LIBRARY(axelib STATIC ${AXELIB_SRCS})
+TARGET_LINK_LIBRARIES(axelib qes_static)
+SET_TARGET_PROPERTIES(axelib PROPERTIES OUTPUT_NAME axe)
+
+# Executable
+ADD_EXECUTABLE(axe main.c)
+TARGET_LINK_LIBRARIES(axe ${AXE_DEPENDS_LIBS} axelib)
+INSTALL(TARGETS axe DESTINATION "bin")
diff --git a/src/axe.c b/src/axe.c
new file mode 100644
index 0000000..b91ed69
--- /dev/null
+++ b/src/axe.c
@@ -0,0 +1,1622 @@
+/*
+ * ============================================================================
+ *
+ * Filename: axe.c
+ *
+ * Description: Demultiplex reads by 5' barcodes
+ *
+ * Version: 1.0
+ * Created: 11/06/14 12:17:17
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "axe.h"
+#include "gsl_combination.h"
+
+/* Holds the current timestamp, so we don't have to free the returned string
+ * from now(). */
+char _time_now[10] = "";
+
+const char *progress_bar_chars = "|/-\\";
+unsigned int format_call_number;
+
+char *
+axe_formatter(struct qes_log_entry *entry)
+{
+ char *buf = NULL;
+ const char *colour = ANSIRST;
+ const char *reset = ANSIRST;
+ char marker = ' ';
+ int res = 0;
+
+ if (entry == NULL || entry->message == NULL) return NULL;
+
+ if (entry->level <= QES_LOG_DEBUG) {
+ marker = '.';
+ colour = ANSIBEG ATDIM FGCYN BGBLK ANSIEND;
+ reset = "";
+ } else if (entry->level == AXE_LOG_PROGRESS) {
+ marker = progress_bar_chars[format_call_number++ % 4];
+ colour = ANSIBEG ATNRM FGGRN BGBLK ANSIEND;
+ } else if (entry->level == AXE_LOG_BOLD) {
+ marker = '\0';
+ colour = ANSIBEG ATBLD FGCYN BGBLK ANSIEND;
+ } else if (entry->level <= QES_LOG_INFO) {
+ marker = '\0';
+ colour = ANSIBEG ATNRM FGGRN BGBLK ANSIEND;
+ } else if (entry->level <= QES_LOG_WARNING) {
+ marker = '!';
+ colour = ANSIBEG ATULN FGYEL BGBLK ANSIEND;
+ } else if (entry->level <= QES_LOG_ERROR) {
+ marker = 'E';
+ colour = ANSIBEG ATBLD FGMAG BGBLK ANSIEND;
+ } else {
+ marker = 'F';
+ colour = ANSIBEG ATBLD ATBNK FGRED BGBLK ANSIEND;
+ }
+ if (marker == '\0') {
+ res = asprintf(&buf, "%s%s%s", colour, entry->message, reset);
+ } else {
+ res = asprintf(&buf, "%s[%c] %s%s", colour, marker, entry->message, reset);
+ }
+ if (res > 0) {
+ return buf;
+ } else {
+ return NULL;
+ }
+}
+
+/* Axe barcode struct ctor/dtor */
+
+struct axe_barcode *
+axe_barcode_create(void)
+{
+ struct axe_barcode *bcd = NULL;
+
+ bcd = qes_calloc(1, sizeof(*bcd));
+ return bcd;
+}
+
+void
+axe_barcode_destroy_(struct axe_barcode *barcode)
+{
+ if (!axe_barcode_ok(barcode)) return;
+ qes_free(barcode->seq1);
+ qes_free(barcode->seq2);
+ qes_free(barcode->id);
+ barcode->len1 = 0;
+ barcode->len2 = 0;
+ qes_free(barcode);
+}
+
+/* Axe config struct ctor/dtor */
+
+struct axe_config *
+axe_config_create(void)
+{
+ struct axe_config *config = qes_calloc(1, sizeof(*config));
+
+ config->logger = qes_logger_create();
+ /* qes_calloc never returns null, we use errprintexit as the err handler */
+ return config;
+}
+
+void
+axe_config_destroy_(struct axe_config *config)
+{
+ size_t iii = 0;
+
+ if (config == NULL) {
+ return;
+ }
+ qes_log_message_debug(config->logger,
+ "Destroying config structure\n");
+ /* File names */
+ qes_free(config->barcode_file);
+ qes_free(config->table_file);
+ qes_free(config->out_prefixes[0]);
+ qes_free(config->out_prefixes[1]);
+ qes_free(config->infiles[0]);
+ qes_free(config->infiles[1]);
+ /* outputs */
+ if (config->outputs != NULL) {
+ for (iii = 0; iii < config->n_barcode_pairs; iii ++) {
+ axe_output_destroy(config->outputs[iii]);
+ }
+ }
+ qes_free(config->outputs);
+ axe_output_destroy(config->unknown_output);
+ /* barcode pairs */
+ if (config->barcodes != NULL) {
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ axe_barcode_destroy(config->barcodes[iii]);
+ }
+ }
+ qes_free(config->barcodes);
+ /* barcode lookup */
+ if (config->barcode_lookup != NULL) {
+ for (iii = 0; iii < config->n_barcodes_1; iii++) {
+ qes_free(config->barcode_lookup[iii]);
+ }
+ }
+ qes_free(config->barcode_lookup);
+ /* Tries */
+ axe_trie_destroy(config->fwd_trie);
+ axe_trie_destroy(config->rev_trie);
+ /* Logger */
+ qes_logger_destroy(config->logger);
+ /* config stuct */
+ qes_free(config);
+}
+
+
+static char *
+_axe_format_outfile_path (const char *prefix, const char *id, int read,
+ const char *ext)
+{
+ char buf[4096];
+ int res = 0;
+ char *our_prefix = NULL;
+ char lastchr = '\0';
+ size_t prefix_len = 0;
+
+ if (prefix == NULL || id == NULL) {
+ return NULL;
+ }
+
+ prefix_len = strlen(prefix);
+ lastchr = prefix[prefix_len - 1];
+ if (lastchr == '/' || lastchr == '\\') {
+ /* Our prefix is a directory, don't add '_' */
+ our_prefix = strdup(prefix);
+ } else {
+ /* Duplicate and append an underscore to prefix */
+ our_prefix = qes_malloc(prefix_len + 2);
+ our_prefix[prefix_len + 1] = '\0';
+ strncpy(our_prefix, prefix, prefix_len);
+ our_prefix[prefix_len] = '_';
+ }
+
+ if (read > 0) {
+ res = snprintf(buf, 4096, "%s%s_R%d.%s", our_prefix, id, read, ext);
+ } else {
+ res = snprintf(buf, 4096, "%s%s_il.%s", our_prefix, id, ext);
+ }
+ if (res >= 4096) {
+ qes_free(our_prefix);
+ return NULL;
+ }
+ qes_free(our_prefix);
+ return strndup(buf, 4096);
+}
+
+struct axe_output *
+axe_output_create(const char *fwd_fpath, const char *rev_fpath,
+ enum read_mode mode, const char *fp_mode)
+{
+ struct axe_output *out = NULL;
+
+ if (mode == READS_UNKNOWN || fwd_fpath == NULL || \
+ (mode == READS_PAIRED && rev_fpath == NULL)) {
+ return NULL;
+ }
+ out = qes_calloc(1, sizeof(*out));
+ out->mode = mode;
+ out->fwd_file = qes_seqfile_create(fwd_fpath, fp_mode);
+ if (out->fwd_file == NULL) {
+ qes_free(out);
+ return NULL;
+ }
+ qes_seqfile_set_format(out->fwd_file, FASTQ_FMT);
+ if (rev_fpath != NULL) {
+ out->rev_file = qes_seqfile_create(rev_fpath, fp_mode);
+ if (out->rev_file == NULL) {
+ qes_seqfile_destroy(out->fwd_file);
+ qes_free(out);
+ return NULL;
+ }
+ qes_seqfile_set_format(out->rev_file, FASTQ_FMT);
+ } else {
+ out->rev_file = NULL;
+ }
+ return out;
+}
+
+void
+axe_output_destroy_(struct axe_output *output)
+{
+ if (output != NULL) {
+ qes_seqfile_destroy(output->fwd_file);
+ qes_seqfile_destroy(output->rev_file);
+ output->mode = READS_UNKNOWN;
+ qes_free(output);
+ }
+}
+
+static inline struct axe_barcode *
+read_barcode_combo(char *line)
+{
+ char seq1[100] = "";
+ char seq2[100] = "";
+ char id[100] = "";
+ int res = 0;
+ struct axe_barcode *barcode = NULL;
+
+ if (line == NULL) {
+ return NULL;
+ }
+ res = sscanf(line, "%99s\t%99s\t%99s", seq1, seq2, id);
+ if (res < 3) {
+ return NULL;
+ }
+ barcode = axe_barcode_create();
+ if (barcode == NULL) {
+ return NULL;
+ }
+ /* Duplicate on the heap the R1 seq */
+ barcode->seq1 = strndup(seq1, 100);
+ if (barcode->seq1 == NULL) goto error;
+ barcode->len1 = strnlen(seq1, 100);
+ /* Second barcode too */
+ barcode->seq2 = strndup(seq2, 100);
+ if (barcode->seq2 == NULL) goto error;
+ barcode->len2 = strnlen(seq2, 100);
+ /* And the ID */
+ barcode->id = strndup(id, 100);
+ if (barcode->id == NULL) goto error;
+ barcode->idlen = strnlen(id, 100);
+ return barcode;
+
+error:
+ axe_barcode_destroy(barcode);
+ return NULL;
+}
+
+static inline struct axe_barcode *
+read_barcode_single(char *line)
+{
+ char seq[100] = "";
+ char id[100] = "";
+ int res = 0;
+ struct axe_barcode * barcode = NULL;
+
+ if (line == NULL) {
+ return NULL;
+ }
+ res = sscanf(line, "%99s\t%99s", seq, id);
+ if (res < 2) {
+ return NULL;
+ }
+ barcode = axe_barcode_create();
+ if (barcode == NULL) {
+ return NULL;
+ }
+ /* Duplicate on the heap the R1 seq */
+ barcode->seq1 = strndup(seq, 100);
+ if (barcode->seq1 == NULL) goto error;
+ barcode->len1 = strnlen(seq, 100);
+ /* And the ID */
+ barcode->id = strndup(id, 100);
+ if (barcode->id == NULL) goto error;
+ barcode->idlen = strnlen(id, 100);
+ return barcode;
+
+error:
+ axe_barcode_destroy(barcode);
+ return NULL;
+}
+
+int
+axe_read_barcodes(struct axe_config *config)
+{
+ struct qes_file *qf = NULL;
+ struct axe_barcode *this_barcode = NULL;
+ struct axe_barcode **barcodes = NULL;
+ size_t n_barcode_pairs = 0; /* Entries in file */
+ size_t n_barcodes_alloced = 8;
+ const char *bad_fname_chars = "'\"!@#$%^&*()+=~`[]{}\\|;:/?><,";
+ char *line = NULL;
+ char *tmp = NULL;
+ size_t linesz = 128;
+ ssize_t linelen = 0;
+ size_t iii = 0;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ barcodes = qes_calloc(n_barcodes_alloced, sizeof(*barcodes));
+ qf = qes_file_open(config->barcode_file, "r");
+ line = qes_malloc(linesz);
+
+ while ((linelen = qes_file_readline_realloc(qf, &line, &linesz)) > 0) {
+ /* Skip an optional header line */
+ if (strncmp(line, "Barcode", 7) == 0 || \
+ strncmp(line, "barcode", 7) == 0) {
+ continue;
+ }
+ /* Skip #-comment or ;-comment */
+ if (line[0] == '#' || line[0] == ';') {
+ continue;
+ }
+ /* Reallocate the array if we need to */
+ if (n_barcode_pairs == n_barcodes_alloced) {
+ n_barcodes_alloced *= 2;
+ barcodes = qes_realloc(barcodes,
+ n_barcodes_alloced * sizeof(*barcodes));
+ }
+ /* Read the barcode line into a ``struct axe_barcode`` */
+ if (config->match_combo) {
+ this_barcode = read_barcode_combo(line);
+ } else {
+ this_barcode = read_barcode_single(line);
+ }
+ if (this_barcode == NULL) {
+ qes_log_format_fatal(config->logger,
+ "Couldn't parse barcode line '%s'\n", line);
+ qes_log_message_warning(config->logger,
+ "Check that the format is correct and has "
+ "UNIX line endings.");
+ goto error;
+ }
+ /* Replace all bad chars with '-' */
+ tmp = strpbrk(this_barcode->id, bad_fname_chars);
+ while (tmp != NULL) {
+ *tmp = '-'; /* Replace with dash */
+ tmp = strpbrk(tmp + 1, bad_fname_chars);
+ }
+ /* Add the barcode to the array */
+ barcodes[n_barcode_pairs++] = this_barcode;
+ }
+
+ /* Save the array to the config struct */
+ config->barcodes = barcodes;
+ config->n_barcode_pairs = n_barcode_pairs;
+ qes_file_close(qf);
+ qes_free(line);
+ if (config->verbosity > 0) {
+ qes_log_format_info(config->logger,
+ "read_barcodes -- (%s) Read in barcodes\n",
+ nowstr());
+ }
+ return 0;
+
+error:
+ if (barcodes != NULL) {
+ for (iii = 0; iii < n_barcode_pairs; iii++) {
+ axe_barcode_destroy(barcodes[iii]);
+ }
+ }
+ qes_file_close(qf);
+ qes_free(line);
+ return 1;
+}
+
+static int
+setup_barcode_lookup_single(struct axe_config *config)
+{
+ size_t iii = 0;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ config->n_barcodes_1 = config->n_barcode_pairs;
+ config->n_barcodes_2 = 0;
+ config->barcode_lookup = qes_malloc(config->n_barcodes_1 *
+ sizeof(*config->barcode_lookup));
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ config->barcode_lookup[iii] = qes_malloc(
+ sizeof(**config->barcode_lookup));
+ config->barcode_lookup[iii][0] = iii;
+ }
+ return 0;
+}
+
+static int
+setup_barcode_lookup_combo(struct axe_config *config)
+{
+ struct axe_barcode *this_barcode = NULL;
+ size_t n_barcodes_1 = 0; /* R1 barcodes */
+ size_t n_barcodes_2 = 0;
+ size_t iii = 0;
+ intptr_t tmp = 0;
+ int ret = -1;
+ int res = 0;
+ size_t bcd1 = 0;
+ size_t bcd2 = 0;
+ struct axe_trie *seq1_trie = NULL;
+ struct axe_trie *seq2_trie = NULL;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ /* Make "hash table" of barcode => unique bcd num. We use tries, as they
+ work fine as a associatve map, and we've already got the headers, lib
+ etc in the system. */
+ seq1_trie = axe_trie_create();
+ seq2_trie = axe_trie_create();
+ assert(seq1_trie != NULL && seq2_trie != NULL);
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_barcode = config->barcodes[iii];
+ if (!axe_barcode_ok(this_barcode)) {
+ qes_log_format_fatal(config->logger,
+ "setup_lookup -- Bad barcode at %" PRIu64 "\n",
+ iii);
+ goto error;
+ }
+ if (!axe_trie_get(seq1_trie, this_barcode->seq1, &tmp)) {
+ axe_trie_add(seq1_trie, this_barcode->seq1, n_barcodes_1++);
+ }
+ if (!axe_trie_get(seq2_trie, this_barcode->seq2, &tmp)) {
+ axe_trie_add(seq2_trie, this_barcode->seq2, n_barcodes_2++);
+ }
+ }
+ config->n_barcodes_1 = n_barcodes_1;
+ config->n_barcodes_2 = n_barcodes_2;
+ /* Make barcode lookup */
+ config->barcode_lookup = qes_malloc(n_barcodes_1 *
+ sizeof(*config->barcode_lookup));
+ for (bcd1 = 0; bcd1 < config->n_barcodes_1; bcd1++) {
+ config->barcode_lookup[bcd1] = qes_calloc(n_barcodes_2,
+ sizeof(**config->barcode_lookup));
+ memset(config->barcode_lookup[bcd1], -1,
+ n_barcodes_2 * sizeof(**config->barcode_lookup));
+ }
+ /* Setup barcode lookup */
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_barcode = config->barcodes[iii];
+ /* already checked barcode above */
+ res = axe_trie_get(seq1_trie, this_barcode->seq1,
+ (intptr_t *)(&bcd1));
+ if (!res) goto error;
+ res = axe_trie_get(seq2_trie, this_barcode->seq2,
+ (intptr_t *)(&bcd2));
+ if (!res) goto error;
+ config->barcode_lookup[bcd1][bcd2] = iii;
+ }
+ ret = 0;
+
+exit:
+ axe_trie_destroy(seq1_trie);
+ axe_trie_destroy(seq2_trie);
+ return ret;
+
+error:
+ ret = 1;
+ goto exit;
+}
+
+int
+axe_setup_barcode_lookup(struct axe_config *config)
+{
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ if (config->match_combo) {
+ return setup_barcode_lookup_combo(config);
+ }
+ return setup_barcode_lookup_single(config);
+}
+
+int
+axe_make_tries(struct axe_config *config)
+{
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ config->fwd_trie = axe_trie_create();
+ if (config->fwd_trie == NULL) {
+ goto error;
+ }
+ if (config->match_combo) {
+ config->rev_trie = axe_trie_create();
+ if (config->rev_trie == NULL) {
+ goto error;
+ }
+ }
+ return 0;
+
+error:
+ qes_log_message_fatal(
+ config->logger,
+ "make_tries -- ERROR: axe_trie_create returned NULL\n");
+ axe_trie_destroy(config->fwd_trie);
+ if (config->match_combo) {
+ axe_trie_destroy(config->rev_trie);
+ }
+ return 1;
+}
+
+static char *
+axe_make_file_ext(const struct axe_config *config)
+{
+ if (!axe_config_ok(config)) {
+ return NULL;
+ }
+ if (config->out_compress_level > 0 &&
+ config->out_compress_level < 10) {
+ return strdup("fastq.gz");
+ }
+ return strdup("fastq");
+}
+
+static char *
+axe_make_zmode(const struct axe_config *config)
+{
+ if (!axe_config_ok(config)) {
+ return NULL;
+ }
+ if (config->out_compress_level > 0 &&
+ config->out_compress_level < 10) {
+ char tmp[3] = "";
+ snprintf(tmp, 3, "w%d", config->out_compress_level);
+ return strdup(tmp);
+ }
+ return strdup("wT");
+}
+
+static inline int
+load_tries_combo(struct axe_config *config)
+{
+ int bcd1 = -1;
+ int bcd2 = -1;
+ int retval = 0;
+ char **mutated = NULL;
+ size_t num_mutated = 0;
+ int ret = 0;
+ size_t iii = 0;
+ size_t jjj = 0;
+ size_t mmm = 0;
+ struct axe_barcode *this_bcd = NULL;
+ intptr_t tmp = 0;
+
+ if (!axe_config_ok(config)) {
+ fprintf(stderr, "[load_tries] Bad config\n");
+ ret = -1;
+ goto exit;
+ }
+ /* Make mutated barcodes and add to trie */
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_bcd = config->barcodes[iii];
+ if (!axe_barcode_ok(this_bcd)) {
+ qes_log_format_fatal(config->logger,
+ "load_tries -- Bad R1 barcode at %" PRIu64 "\n", iii);
+ ret = -1;
+ goto exit;
+ }
+ /* Either lookup the index of the first read in the barcode table, or
+ * insert this barcode into the table, storing its index.
+ * Note the NOT here. */
+ if (!axe_trie_get(config->fwd_trie, this_bcd->seq1, &tmp)) {
+ ret = axe_trie_add(config->fwd_trie, this_bcd->seq1, ++bcd1);
+ if (ret != 0) {
+ qes_log_format_fatal(config->logger,
+ "load_tries -- Could not load barcode %s into trie %" PRIu64 "\n",
+ this_bcd->seq1, iii);
+ ret = 1;
+ goto exit;
+ }
+ } else {
+ continue;
+ }
+ for (jjj = 1; jjj <= config->mismatches; jjj++) {
+ /* Do the forwards read barcode */
+ mutated = hamming_mutate_dna(&num_mutated, this_bcd->seq1,
+ this_bcd->len1, jjj, 0);
+ if (mutated == NULL) {
+ ret = 1;
+ goto exit;
+ }
+ for (mmm = 0; mmm < num_mutated; mmm++) {
+ ret = axe_trie_add(config->fwd_trie, mutated[mmm], bcd1);
+ if (ret != 0) {
+ if (config->permissive) {
+ if (config->verbosity >= 0) {
+ qes_log_format_warning(config->logger,
+ "load_tries -- warning: Will only match to %dmm\n",
+ (int)jjj - 1);
+ }
+ axe_trie_delete(config->fwd_trie, mutated[mmm]);
+ qes_free(mutated[mmm]);
+ continue;
+ }
+ qes_log_format_fatal(config->logger,
+ "load_tries -- Barcode %s already in fwd trie (%dmm) %s\n",
+ mutated[mmm], (int)jjj, this_bcd->seq1);
+ retval = 1;
+ goto exit;
+ }
+ qes_free(mutated[mmm]);
+ }
+ qes_free(mutated);
+ }
+ }
+ /* Ditto for the reverse read */
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_bcd = config->barcodes[iii];
+ /* Likewise for the reverse read index */
+ if (!axe_trie_get(config->rev_trie, this_bcd->seq2, &tmp)) {
+ ret = axe_trie_add(config->rev_trie, this_bcd->seq2, ++bcd2);
+ if (ret != 0) {
+ qes_log_format_fatal(config->logger,
+ "load_tries -- Could not load barcode %s into trie %" PRIu64 "\n",
+ this_bcd->seq2, iii);
+ retval = 1;
+ goto exit;
+ }
+ } else {
+ continue;
+ }
+ for (jjj = 1; jjj <= config->mismatches; jjj++) {
+ num_mutated = 0;
+ mutated = hamming_mutate_dna(&num_mutated, this_bcd->seq2,
+ this_bcd->len2, jjj, 0);
+ if (mutated == NULL) {
+ ret = 1;
+ goto exit;
+ }
+ for (mmm = 0; mmm < num_mutated; mmm++) {
+ ret = axe_trie_add(config->rev_trie, mutated[mmm], bcd2);
+ if (ret != 0) {
+ if (config->permissive) {
+ if (config->verbosity >= 0) {
+ qes_log_format_warning(config->logger,
+ "load_tries -- Will only match %s to %dmm\n",
+ this_bcd->id, (int)jjj - 1);
+ }
+ trie_delete(config->rev_trie->trie,
+ mutated[mmm]);
+ qes_free(mutated[mmm]);
+ continue;
+ }
+ qes_log_format_fatal(config->logger,
+ "load_tries -- Barcode %s already in rev trie (%dmm) %s\n",
+ mutated[mmm], (int)jjj, this_bcd->seq1);
+ retval = 1;
+ goto exit;
+ }
+ qes_free(mutated[mmm]);
+ }
+ qes_free(mutated);
+ }
+ }
+ /* we got here, so we succeeded. set retval accordingly */
+ retval = 0;
+
+exit:
+ if (mutated != NULL) {
+ for (mmm = 0; mmm < num_mutated; mmm++) {
+ qes_free(mutated[mmm]);
+ }
+ qes_free(mutated);
+ }
+ return retval;
+}
+
+static inline int
+load_tries_single(struct axe_config *config)
+{
+ char **mutated = NULL;
+ size_t num_mutated = 0;
+ int ret = 0;
+ size_t iii = 0;
+ size_t jjj = 0;
+ size_t mmm = 0;
+ intptr_t tmp = 0;
+ int retval = -1;
+ struct axe_barcode *this_bcd = NULL;
+
+ if (!axe_config_ok(config)) {
+ fprintf(stderr, "[load_tries] Bad config\n");
+ return -1;
+ }
+ /* Make mutated barcodes and add to trie */
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_bcd = config->barcodes[iii];
+ if (!axe_barcode_ok(this_bcd)) {
+ fprintf(stderr, "[load_tries] Bad barcode at %" PRIu64 "\n", iii);
+ return -1;
+ }
+ /* Either lookup the index of the first read in the barcode table, or
+ * insert this barcode into the table, storing its index.
+ * Note the NOT here. */
+ if (!axe_trie_get(config->fwd_trie, this_bcd->seq1, &tmp)) {
+ ret = axe_trie_add(config->fwd_trie, this_bcd->seq1, (int)iii);
+ if (ret != 0) {
+ fprintf(stderr,
+ "ERROR: Could not load barcode %s into trie %" PRIu64 "\n",
+ this_bcd->seq1, iii);
+ return 1;
+ }
+ } else {
+ fprintf(stderr, "ERROR: Duplicate barcode %s\n", this_bcd->seq1);
+ return 1;
+ }
+ for (jjj = 1; jjj <= config->mismatches; jjj++) {
+ mutated = hamming_mutate_dna(&num_mutated, this_bcd->seq1,
+ this_bcd->len1, jjj, 0);
+ if (mutated == NULL) {
+ ret = 1;
+ goto exit;
+ }
+ for (mmm = 0; mmm < num_mutated; mmm++) {
+ ret = axe_trie_add(config->fwd_trie, mutated[mmm], iii);
+ if (ret != 0) {
+ if (config->permissive) {
+ if (config->verbosity >= 0) {
+ fprintf(stderr,
+ "[%s] warning: Will only match to %dmm\n",
+ __func__, (int)jjj - 1);
+ }
+ trie_delete(config->fwd_trie->trie,
+ mutated[mmm]);
+ qes_free(mutated[mmm]);
+ continue;
+ }
+ fprintf(stderr,
+ "[%s] ERROR: Barcode %s already in trie (%dmm)\n",
+ __func__, mutated[mmm], (int)jjj);
+ retval = 1;
+ goto exit;
+ }
+ qes_free(mutated[mmm]);
+ }
+ qes_free(mutated);
+ num_mutated = 0;
+ }
+ }
+ /* we got here, so we succeeded */
+ retval = 0;
+
+exit:
+ if (mutated != NULL) {
+ for (mmm = 0; mmm < num_mutated; mmm++) {
+ qes_free(mutated[mmm]);
+ }
+ qes_free(mutated);
+ }
+ return retval;
+}
+
+int
+axe_make_outputs(struct axe_config *config)
+{
+ size_t iii = 0;
+ char *name_fwd = NULL;
+ char *name_rev = NULL;
+ char *file_ext = NULL;
+ char *zmode = NULL;
+ struct axe_barcode *this_bcd = NULL;
+
+ if (!axe_config_ok(config)) {
+ fprintf(stderr, "[make_outputs] Bad config\n");
+ return -1;
+ }
+ file_ext = axe_make_file_ext(config);
+ zmode = axe_make_zmode(config);
+ config->outputs = qes_calloc(config->n_barcode_pairs,
+ sizeof(*config->outputs));
+ /* For each sample, make the filename, make an output */
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_bcd = config->barcodes[iii];
+ /* Open barcode files */
+ switch (config->out_mode) {
+ case READS_SINGLE:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ this_bcd->id, 1, file_ext);
+ name_rev = NULL;
+ break;
+ case READS_PAIRED:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ this_bcd->id, 1, file_ext);
+ name_rev = _axe_format_outfile_path(config->out_prefixes[1],
+ this_bcd->id, 2, file_ext);
+ break;
+ case READS_INTERLEAVED:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ this_bcd->id, 0, file_ext);
+ name_rev = NULL;
+ break;
+ case READS_UNKNOWN:
+ default:
+ fprintf(stderr, "[make_outputs] Error: bad output mode %ui\n",
+ config->out_mode);
+ goto error;
+ }
+ config->outputs[iii] = axe_output_create(name_fwd, name_rev,
+ config->out_mode, zmode);
+
+ if (config->outputs[iii] == NULL) {
+ fprintf(stderr, "[make_outputs] couldn't create file at %s\n",
+ name_fwd);
+ goto error;
+ }
+ qes_free(name_fwd);
+ qes_free(name_rev);
+ }
+ /* Generate the unknown file in the same manner, using id == unknown */
+ switch (config->out_mode) {
+ case READS_SINGLE:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ "unknown", 1, file_ext);
+ name_rev = NULL;
+ break;
+ case READS_PAIRED:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ "unknown", 1, file_ext);
+ name_rev = _axe_format_outfile_path(config->out_prefixes[1],
+ "unknown", 2, file_ext);
+ break;
+ case READS_INTERLEAVED:
+ name_fwd = _axe_format_outfile_path(config->out_prefixes[0],
+ "unknown", 0, file_ext);
+ name_rev = NULL;
+ break;
+ case READS_UNKNOWN:
+ default:
+ fprintf(stderr, "[make_outputs] Error: bad output mode %ui\n",
+ config->out_mode);
+ goto error;
+ }
+ config->unknown_output = axe_output_create(name_fwd, name_rev,
+ config->out_mode, zmode);
+ if (config->unknown_output == NULL) {
+ fprintf(stderr, "[make_outputs] couldn't create file at %s\n",
+ name_fwd);
+ goto error;
+ }
+ qes_free(file_ext);
+ qes_free(zmode);
+ return 0;
+
+error:
+ qes_free(name_fwd);
+ qes_free(name_rev);
+ qes_free(file_ext);
+ qes_free(zmode);
+ return 1;
+}
+
+int
+axe_load_tries(struct axe_config *config)
+{
+ int ret = 1;
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ if (config->match_combo) {
+ ret = load_tries_combo(config);
+ } else {
+ ret = load_tries_single(config);
+ }
+ if (config->verbosity > 0) {
+ fprintf(stderr, "[load_tries] (%s) Barcode tries loaded\n",
+ nowstr());
+ }
+ return ret;
+}
+
+static inline int
+write_barcoded_read_combo(struct axe_output *out, struct qes_seq *seq1,
+ struct qes_seq *seq2, size_t bcd1_len,
+ size_t bcd2_len)
+{
+ int ret = 0;
+
+ if (seq1->seq.len <= bcd1_len) {
+ /* Truncate seqs to N */
+ seq1->seq.str[0] = 'N';
+ seq1->seq.str[1] = '\0';
+ seq1->seq.len = 1;
+ /* Keep first qual 'base' */
+ seq1->qual.str[1] = '\0';
+ seq1->qual.len = 1;
+ }
+ if (seq2->seq.len <= bcd2_len) {
+ /* Truncate seqs to N */
+ seq2->seq.str[0] = 'N';
+ seq2->seq.str[1] = '\0';
+ seq2->seq.len = 1;
+ /* Keep first qual 'base' */
+ seq2->qual.str[1] = '\0';
+ seq2->qual.len = 1;
+ }
+ /* Bit of the ol' switcheroo. We keep the seq's char pointers, so we
+ need to switch them back to their orig. values, but don't want to
+ copy. Kludgy, I know. */
+ seq1->seq.str += bcd1_len;
+ seq1->seq.len -= bcd1_len;
+ seq1->qual.str += bcd1_len;
+ seq1->qual.len -= bcd1_len;
+ ret = qes_seqfile_write(out->fwd_file, seq1);
+ if (ret < 1) {
+ fprintf(stderr,
+ "[process_file] Error: writing to fwd file %s failed\n%s\n",
+ out->fwd_file->qf->path,
+ qes_file_error(out->fwd_file->qf));
+ seq1->seq.str -= bcd1_len;
+ seq1->seq.len += bcd1_len;
+ seq1->qual.str -= bcd1_len;
+ seq1->qual.len += bcd1_len;
+ return 1;
+ }
+ seq1->seq.str -= bcd1_len;
+ seq1->seq.len += bcd1_len;
+ seq1->qual.str -= bcd1_len;
+ seq1->qual.len += bcd1_len;
+ seq2->seq.str += bcd2_len;
+ seq2->seq.len -= bcd2_len;
+ seq2->qual.str += bcd2_len;
+ seq2->qual.len -= bcd2_len;
+ if (out->mode == READS_INTERLEAVED) {
+ ret = qes_seqfile_write(out->fwd_file, seq2);
+ if (ret < 1) {
+ fprintf(stderr,
+ "[process_file] Error: writing to il file %s failed\n%s\n",
+ out->fwd_file->qf->path,
+ qes_file_error(out->fwd_file->qf));
+ return 1;
+ }
+ } else if (out->mode == READS_PAIRED) {
+ ret = qes_seqfile_write(out->rev_file, seq2);
+ if (ret < 1) {
+ fprintf(stderr,
+ "process_file -- Error: writing to rev file %s failed\n%s\n",
+ out->rev_file->qf->path,
+ qes_file_error(out->rev_file->qf));
+ return 1;
+ }
+ }
+ seq2->seq.str -= bcd2_len;
+ seq2->seq.len += bcd2_len;
+ seq2->qual.str -= bcd2_len;
+ seq2->qual.len += bcd2_len;
+ return 0;
+}
+
+static inline void
+increment_reads_print_progress(struct axe_config *config)
+{
+ config->reads_processed++;
+ if (config->reads_processed % 100000 == 0) {
+ if (config->verbosity >= 0) {
+ axe_format_progress(config->logger,
+ "%s: Processed %.1fM %s\r",
+ nowstr(),
+ (float)(config->reads_processed/1000000.0),
+ config->out_mode == READS_SINGLE ? "reads" : "read pairs");
+ }
+ }
+}
+
+static inline int
+process_read_pair_single(struct axe_config *config, struct qes_seq *seq1,
+ struct qes_seq *seq2)
+{
+ int ret = 0;
+ ssize_t bcd = -1;
+ size_t barcode_pair_index = 0;
+ struct axe_output *outfile = NULL;
+ size_t bcd_len = 0;
+
+ ret = axe_match_read(config, &bcd, config->fwd_trie, seq1);
+ increment_reads_print_progress(config);
+ if (ret != 0) {
+ /* No match */
+ qes_seqfile_write(config->unknown_output->fwd_file, seq1);
+ if (seq2 != NULL) {
+ if (config->out_mode == READS_INTERLEAVED) {
+ qes_seqfile_write(config->unknown_output->fwd_file, seq2);
+ } else {
+ qes_seqfile_write(config->unknown_output->rev_file, seq2);
+ }
+ }
+ config->reads_failed++;
+ return 0;
+ }
+ /* Found a match */
+ config->reads_demultiplexed++;
+ /* FIXME: we need to check bcd doesn't cause segfault */
+ barcode_pair_index = config->barcode_lookup[bcd][0];
+ outfile = config->outputs[barcode_pair_index];
+ bcd_len = config->barcodes[barcode_pair_index]->len1;
+ config->barcodes[bcd]->count++;
+ if (seq1->seq.len <= bcd_len) {
+ /* Don't write out seqs shorter than the barcode */
+ return 0;
+ }
+ /* Bit of the ol' switcheroo. We keep the seq's char pointers, so we need
+ * to switch them back to their orig. values, but don't want to copy.
+ * Kludgy, I know. */
+ seq1->seq.str += bcd_len;
+ seq1->seq.len -= bcd_len;
+ seq1->qual.str += bcd_len;
+ seq1->qual.len -= bcd_len;
+ ret = qes_seqfile_write(outfile->fwd_file, seq1);
+ if (ret < 1) {
+ fprintf(stderr,
+ "[write_read_single] Error: writing to R1 file %s failed\n%s\n",
+ outfile->fwd_file->qf->path,
+ qes_file_error(outfile->fwd_file->qf));
+ seq1->seq.str -= bcd_len;
+ seq1->seq.len += bcd_len;
+ seq1->qual.str -= bcd_len;
+ seq1->qual.len += bcd_len;
+ return 1;
+ }
+ seq1->seq.str -= bcd_len;
+ seq1->seq.len += bcd_len;
+ seq1->qual.str -= bcd_len;
+ seq1->qual.len += bcd_len;
+ /* And do the same with seq2, if we have one */
+ if (seq2 != NULL) {
+ if (config->trim_rev) {
+ seq2->seq.str += bcd_len;
+ seq2->seq.len -= bcd_len;
+ seq2->qual.str += bcd_len;
+ seq2->qual.len -= bcd_len;
+ }
+ if (outfile->mode == READS_INTERLEAVED) {
+ ret = qes_seqfile_write(outfile->fwd_file, seq2);
+ if (ret < 1) {
+ qes_log_format_fatal(
+ config->logger,
+ "process_file -- Writing to file %s failed\n%s\n",
+ outfile->fwd_file->qf->path,
+ qes_file_error(outfile->fwd_file->qf));
+ return 1;
+ }
+ } else if (outfile->mode == READS_PAIRED) {
+ ret = qes_seqfile_write(outfile->rev_file, seq2);
+ if (ret < 1) {
+ qes_log_format_fatal(
+ config->logger,
+ "process_file -- Writing to file %s failed\n%s\n",
+ outfile->rev_file->qf->path,
+ qes_file_error(outfile->rev_file->qf));
+ return 1;
+ }
+ }
+ if (config->trim_rev) {
+ seq2->seq.str -= bcd_len;
+ seq2->seq.len += bcd_len;
+ seq2->qual.str -= bcd_len;
+ seq2->qual.len += bcd_len;
+ }
+ }
+ return 0;
+}
+
+
+static int
+process_file_single(struct axe_config *config)
+{
+ struct qes_seqfile *fwdsf = NULL;
+ struct qes_seqfile *revsf = NULL;
+ int ret = 0;
+ int retval = -1;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ fwdsf = qes_seqfile_create(config->infiles[0], "r");
+ if (fwdsf == NULL) {
+ qes_log_format_fatal(config->logger,
+ "process_file -- Couldn't open seqfile %s\n",
+ config->infiles[0]);
+ goto exit;
+ }
+ switch(config->in_mode) {
+ case READS_SINGLE:
+ goto single;
+ break;
+ case READS_INTERLEAVED:
+ goto interleaved;
+ break;
+ case READS_PAIRED:
+ revsf = qes_seqfile_create(config->infiles[1], "r");
+ if (revsf == NULL) {
+ qes_log_format_fatal(config->logger,
+ "process_file -- Couldn't open seqfile %s\n",
+ config->infiles[1]);
+ goto exit;
+ }
+ goto paired;
+ break;
+ case READS_UNKNOWN:
+ default:
+ qes_log_format_fatal(config->logger,
+ "process_file_single -- Bad infile mode %u\n",
+ config->in_mode);
+ goto exit;
+ break;
+ }
+
+single:
+ QES_SEQFILE_ITER_SINGLE_BEGIN(fwdsf, seq, seqlen) {
+ ret = process_read_pair_single(config, seq, NULL);
+ }
+ QES_SEQFILE_ITER_SINGLE_END(seq);
+ retval = ret == 0 ? 0 : 1;
+ goto exit;
+
+interleaved:
+ QES_SEQFILE_ITER_INTERLEAVED_BEGIN(fwdsf, seq1, seq2, seqlen1, seqlen2) {
+ ret = process_read_pair_single(config, seq1, seq2);
+ }
+ QES_SEQFILE_ITER_INTERLEAVED_END(seq1, seq2);
+ retval = ret == 0 ? 0 : 1;
+ goto exit;
+
+paired:
+ QES_SEQFILE_ITER_PAIRED_BEGIN(fwdsf, revsf, seq1, seq2, seqlen1, seqlen2) {
+ ret = process_read_pair_single(config, seq1, seq2);
+ }
+ QES_SEQFILE_ITER_PAIRED_END(seq1, seq2);
+ retval = ret == 0 ? 0 : 1;
+ goto exit;
+exit:
+ qes_seqfile_destroy(fwdsf);
+ qes_seqfile_destroy(revsf);
+ return retval;
+}
+
+
+static int
+process_read_pair_combo(struct axe_config *config, struct qes_seq *seq1,
+ struct qes_seq *seq2)
+{
+ ssize_t barcode_pair_index = 0;
+ intptr_t bcd1 = -1;
+ intptr_t bcd2 = -1;
+ int r1_ret = 0;
+ int r2_ret = 0;
+ size_t bcd1_len = 0;
+ size_t bcd2_len = 0;
+ struct axe_output *outfile = NULL;
+
+ r1_ret = axe_match_read(config, &bcd1, config->fwd_trie, seq1);
+ r2_ret = axe_match_read(config, &bcd2, config->rev_trie, seq2);
+ increment_reads_print_progress(config);
+ if (r1_ret != 0 || r2_ret != 0) {
+ /* No match */
+ qes_seqfile_write(config->unknown_output->fwd_file, seq1);
+ if (config->out_mode == READS_INTERLEAVED) {
+ qes_seqfile_write(config->unknown_output->fwd_file, seq2);
+ } else {
+ qes_seqfile_write(config->unknown_output->rev_file, seq2);
+ }
+ config->reads_failed++;
+ return 0;
+ }
+ /* Found a match */
+ barcode_pair_index = config->barcode_lookup[bcd1][bcd2];
+ if (barcode_pair_index < 0) {
+ /* Invalid match */
+ qes_seqfile_write(config->unknown_output->fwd_file, seq1);
+ if (config->out_mode == READS_INTERLEAVED) {
+ qes_seqfile_write(config->unknown_output->fwd_file, seq2);
+ } else {
+ qes_seqfile_write(config->unknown_output->rev_file, seq2);
+ }
+ config->reads_failed++;
+ return 0;
+ }
+ config->reads_demultiplexed++;
+ outfile = config->outputs[barcode_pair_index];
+ bcd1_len = config->barcodes[barcode_pair_index]->len1;
+ bcd2_len = config->barcodes[barcode_pair_index]->len2;
+ config->barcodes[barcode_pair_index]->count++;
+ return write_barcoded_read_combo(outfile, seq1, seq2, bcd1_len,
+ bcd2_len);
+}
+
+
+static int
+process_file_combo(struct axe_config *config)
+{
+ struct qes_seqfile *fwdsf = NULL;
+ struct qes_seqfile *revsf = NULL;
+ int have_error = 0;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ fwdsf = qes_seqfile_create(config->infiles[0], "r");
+ if (fwdsf == NULL) {
+ qes_log_format_fatal(config->logger,
+ "process_file -- Couldn't open seqfile %s\n",
+ config->infiles[0]);
+ goto error;
+ }
+ switch(config->in_mode) {
+ case READS_INTERLEAVED:
+ goto interleaved;
+ break;
+ case READS_PAIRED:
+ revsf = qes_seqfile_create(config->infiles[1], "r");
+ if (revsf == NULL) {
+ qes_log_format_fatal(config->logger,
+ "process_file -- Couldn't open seqfile %s\n",
+ config->infiles[0]);
+ goto error;
+ }
+ goto paired;
+ break;
+ case READS_SINGLE:
+ case READS_UNKNOWN:
+ default:
+ qes_log_format_fatal(config->logger,
+ "process_file_combo -- Bad infile mode %u\n",
+ config->in_mode);
+ goto error;
+ break;
+ }
+
+interleaved:
+ QES_SEQFILE_ITER_INTERLEAVED_BEGIN(fwdsf, seq1, seq2, seqlen1, seqlen2)
+ if (process_read_pair_combo(config, seq1, seq2)) {
+ have_error = 1;
+ break;
+ }
+ QES_SEQFILE_ITER_INTERLEAVED_END(seq1, seq2)
+ if (!have_error) goto clean_exit;
+ else goto error;
+
+paired:
+ QES_SEQFILE_ITER_PAIRED_BEGIN(fwdsf, revsf, seq1, seq2, seqlen1, seqlen2)
+ if (process_read_pair_combo(config, seq1, seq2)) {
+ have_error = 1;
+ break;
+ }
+ QES_SEQFILE_ITER_PAIRED_END(seq1, seq2)
+ if (!have_error) goto clean_exit;
+ else goto error;
+
+clean_exit:
+ qes_seqfile_destroy(fwdsf);
+ qes_seqfile_destroy(revsf);
+ return 0;
+error:
+ qes_seqfile_destroy(fwdsf);
+ qes_seqfile_destroy(revsf);
+ return 1;
+}
+
+
+int
+axe_process_file(struct axe_config *config)
+{
+ int ret = 0;
+ clock_t start = 0;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ start = clock();
+ if (config->verbosity >= 0) {
+ axe_format_bold(config->logger,
+ "process_file -- (%s) Starting demultiplexing\n",
+ nowstr());
+ }
+ if (config->match_combo) {
+ ret = process_file_combo(config);
+ } else {
+ ret = process_file_single(config);
+ }
+ config->time_taken = (float)(clock() - start) / CLOCKS_PER_SEC;
+ if (config->verbosity >= 0) {
+ /* Jump to new line so we don't clobber the progress bar */
+ fprintf(stderr, "\n");
+ axe_format_bold(config->logger,
+ "process_file -- (%s) Finished demultiplexing\n",
+ nowstr());
+ }
+ return ret;
+}
+
+int
+product(int64_t len, int64_t elem, uintptr_t *choices, int at_start)
+{
+ ssize_t iii = 0;
+ if (len < elem || choices == NULL) {
+ /* error value, so don't use (!ret) as your test for the end of the
+ enclosing while loop, or on error you'll have an infinite loop */
+ return -1;
+ }
+ if (at_start) {
+ /* [0, 0, ..., 0] is a valid set */
+ return 1;
+ }
+ iii = elem - 1;
+ while (iii >= 0) {
+ if (choices[iii] < (uintptr_t)(len - 1)) {
+ /* Woo, we've found something to increment. */
+ ssize_t jjj;
+ /* Increment this choice */
+ choices[iii]++;
+ /* fill forwards with 0. */
+ for (jjj = iii + 1; jjj < elem; jjj++) {
+ choices[jjj] = 0;
+ }
+ return 1;
+ }
+ iii--;
+ }
+ for (iii = 0; iii < elem; iii++) {
+ choices[iii] = 0llu;
+ }
+ return 0;
+}
+
+char **
+hamming_mutate_dna(size_t *n_results_o, const char *str, size_t len,
+ unsigned int dist, int keep_original)
+{
+ const char alphabet[] = "ACGT";
+ const size_t n_letters = 4;
+ char *tmp = NULL;
+ char **result = NULL;
+ size_t results = 0;
+ size_t results_alloced = 64;
+ size_t iii;
+ uint64_t *alphabet_indicies;
+ int alpha_ret = 0;
+ gsl_combination *mut_idx_comb;
+
+ if (str == NULL || len < 1 || dist < 1) {
+ return NULL;
+ }
+ result = qes_malloc(results_alloced * sizeof(*result));
+ alphabet_indicies = qes_calloc(dist, sizeof(*alphabet_indicies));
+ mut_idx_comb = gsl_combination_calloc(len, dist);
+ do {
+ while ((alpha_ret = product(n_letters, dist, alphabet_indicies,
+ !alpha_ret)) == 1) {
+ tmp = strndup(str, len+1);
+ for (iii = 0; iii < dist; iii++) {
+ char replacement = alphabet[alphabet_indicies[iii]];
+ size_t mut_idx = gsl_combination_get(mut_idx_comb, iii);
+ if (tmp[mut_idx] == replacement) {
+ continue;
+ }
+ tmp[mut_idx] = replacement;
+ }
+ if (strncmp(str, tmp, len) == 0 && !keep_original) {
+ qes_free(tmp);
+ continue;
+ } else {
+ if (results + 1 > results_alloced) {
+ results_alloced = qes_roundupz(results_alloced);
+ result = qes_realloc(result,
+ results_alloced * sizeof(*result));
+ }
+ result[results++] = strndup(tmp, len);
+ qes_free(tmp);
+ }
+ }
+ } while (gsl_combination_next(mut_idx_comb) == GSL_SUCCESS);
+ gsl_combination_free(mut_idx_comb);
+ qes_free(alphabet_indicies);
+ *n_results_o = results;
+ return result;
+}
+
+struct axe_trie *
+axe_trie_create(void)
+{
+ struct axe_trie *trie = NULL;
+ AlphaMap *map = alpha_map_new();
+ int ret = 0;
+
+ /* Make trie AlphaMap */
+ if (map == NULL) {
+ return NULL;
+ }
+#define _AM_ADD(chr) \
+ ret = alpha_map_add_range(map, chr, chr); \
+ if (ret != 0) { \
+ fprintf(stderr, "[trie_create] Failed to add char %c to alphamap\n",\
+ chr); \
+ alpha_map_free(map); \
+ return NULL; \
+ }
+ _AM_ADD('A')
+ _AM_ADD('C')
+ _AM_ADD('G')
+ _AM_ADD('T')
+ _AM_ADD('N')
+#undef _AM_ADD
+ trie = qes_calloc(1, sizeof(*trie));
+ trie->trie = trie_new(map);
+ if (trie->trie == NULL) {
+ qes_free(trie);
+ alpha_map_free(map);
+ return NULL;
+ }
+ alpha_map_free(map);
+ return trie;
+}
+
+void
+axe_trie_destroy_(struct axe_trie *trie)
+{
+ if (trie != NULL) {
+ /* trie_free doesn't check for null, so we better */
+ if (trie->trie != NULL) {
+ trie_free(trie->trie);
+ }
+ qes_free(trie);
+ }
+}
+
+inline int
+axe_trie_get(struct axe_trie *trie, const char *str, intptr_t *data)
+{
+ if (!axe_trie_ok(trie) || str == NULL) return -1;
+ return trie_retrieve(trie->trie, str, data);
+}
+
+inline int
+axe_trie_delete(struct axe_trie *trie, const char *str)
+{
+ if (!axe_trie_ok(trie) || str == NULL) return -1;
+ return trie_delete(trie->trie, str);
+}
+
+inline int
+axe_trie_add(struct axe_trie *trie, const char *str, intptr_t data)
+{
+ if (!axe_trie_ok(trie) || str == NULL) return -1;
+ if (trie_store_if_absent(trie->trie, str, data)) {
+ return 0;
+ }
+ return 1;
+}
+
+inline int
+axe_match_read (struct axe_config *config, ssize_t *value,
+ struct axe_trie *trie, const struct qes_seq *seq)
+{
+ TrieState *trie_iter = NULL;
+ TrieState *last_good_state = NULL;
+ size_t seq_pos = 0;
+
+ /* value is set to -1 on anything bad happening including failed lookup */
+ if (value == NULL || !axe_trie_ok(trie) || !qes_seq_ok(seq)) {
+ return -1;
+ }
+ /* Set *value here, then we just don't update it on error */
+ *value = -1;
+ if (seq->seq.len < trie->min_len) {
+ return 1;
+ }
+ /* Only look until the maximum of the largest barcode, or seq len */
+ /* Grab tree root iter, and check it. */
+ trie_iter = trie_root(trie->trie);
+ if (trie_iter == NULL) {
+ qes_log_message_fatal(config->logger,
+ "match_read -- trie_root() returned NULL!\n");
+ return -1;
+ }
+ /* Consume seq until we can't */
+ do {
+ trie_state_walk(trie_iter, seq->seq.str[seq_pos]);
+ if (trie_state_is_terminal(trie_iter)) {
+ if (last_good_state != NULL) {
+ trie_state_free(last_good_state);
+ }
+ last_good_state = trie_state_clone(trie_iter);
+ }
+ } while (trie_state_is_walkable(trie_iter, seq->seq.str[++seq_pos]));
+ /* If we get to a terminal state, then great! */
+ if (trie_state_is_terminal(trie_iter)) {
+ trie_state_walk(trie_iter, '\0');
+ trie_state_free(last_good_state);
+ *value = (ssize_t) trie_state_get_data(trie_iter);
+ trie_state_free(trie_iter);
+ return 0;
+ } else if (last_good_state != NULL) {
+ trie_state_free(trie_iter);
+ trie_state_walk(last_good_state, '\0');
+ *value = (ssize_t) trie_state_get_data(last_good_state);
+ trie_state_free(last_good_state);
+ return 0;
+ }
+ trie_state_free(trie_iter);
+ if (last_good_state != NULL) {
+ trie_state_free(last_good_state);
+ }
+ return 1;
+}
+
+int
+axe_write_table(const struct axe_config *config)
+{
+ FILE *tab_fp = NULL;
+ struct axe_barcode *this_bcd = NULL;
+ size_t iii = 0;
+ int res = 0;
+
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ if (config->table_file == NULL) {
+ /* we always call this function in the main loop, so we bail out here
+ if we don't have a file to write it to. */
+ return 0;
+ }
+ tab_fp = fopen(config->table_file, "w");
+ if (tab_fp == NULL) {
+ qes_log_format_fatal(config->logger, "write_table -- ERROR: Could not open %s\n%s\n",
+ config->table_file, strerror(errno));
+ return 1;
+ }
+ if (config->match_combo) {
+ fprintf(tab_fp, "R1Barcode\tR2Barcode\tSample\tCount\n");
+ } else {
+ fprintf(tab_fp, "Barcode\tSample\tCount\n");
+ }
+ for (iii = 0; iii < config->n_barcode_pairs; iii++) {
+ this_bcd = config->barcodes[iii];
+ if (config->match_combo) {
+ fprintf(tab_fp, "%s\t%s\t%s\t%" PRIu64 "\n", this_bcd->seq1,
+ this_bcd->seq2, this_bcd->id, this_bcd->count);
+ } else {
+ fprintf(tab_fp, "%s\t%s\t%" PRIu64 "\n", this_bcd->seq1,
+ this_bcd->id, this_bcd->count);
+ }
+ }
+ if (config->match_combo) {
+ fprintf(tab_fp, "N\tN\tNo Barcode\t%" PRIu64 "\n",
+ config->reads_failed);
+ } else {
+ fprintf(tab_fp, "N\tNo Barcode\t%" PRIu64 "\n", config->reads_failed);
+ }
+ res = fclose(tab_fp);
+ if (res != 0) {
+ qes_log_format_error(config->logger,
+ "[write_table] Couldn't close tab file %s\n%s\n",
+ config->table_file, strerror(errno));
+ return 1;
+ }
+ return 0;
+}
+
+int
+axe_print_summary(const struct axe_config *config)
+{
+ const char *tmp;
+
+#define million(r) ((float)(r / 1000000.0))
+ if (!axe_config_ok(config)) {
+ return -1;
+ }
+ if (config->verbosity < 0) {
+ /* Say nothing if we're being quiet */
+ return 0;
+ }
+ axe_message_bold(config->logger, "\nRun Summary:\n");
+ if (config->verbosity > 1) {
+ qes_log_message_debug(config->logger,
+ "Being verbose (not that you'll notice)\n");
+ }
+ tmp = config->out_mode == READS_SINGLE ? "reads" : "read pairs";
+ axe_format_bold(config->logger,
+ "Processed %.2fM %s in %0.1f seconds (%0.1fK %s/sec)\n",
+ million(config->reads_processed), tmp, config->time_taken,
+ (float)(config->reads_processed / 1000) / config->time_taken, tmp);
+ axe_format_bold(config->logger,
+ "%.2fM %s contained valid barcodes\n",
+ million(config->reads_demultiplexed), tmp);
+ axe_format_bold(config->logger,
+ "%.2fM %s could not be demultiplexed (%0.1f%%)\n",
+ million(config->reads_failed), tmp,
+ ((float)config->reads_failed/(float)(config->reads_processed)*100.0));
+ return 0;
+}
diff --git a/src/axe.h b/src/axe.h
new file mode 100644
index 0000000..68f6fdd
--- /dev/null
+++ b/src/axe.h
@@ -0,0 +1,283 @@
+/*
+ * ============================================================================
+ *
+ * Filename: axe.h
+ *
+ * Description: Demultiplex reads by 5' barcodes
+ *
+ * Version: 1.0
+ * Created: 11/06/14 12:19:39
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+#ifndef AXE_H
+#define AXE_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <time.h>
+
+#include <qes_util.h>
+#include <qes_seq.h>
+#include <qes_seqfile.h>
+#include <qes_log.h>
+
+#include "datrie/trie.h"
+#include "datrie/alpha-map.h"
+#include "axe_config.h"
+
+/* General rules:
+ * Most functions are declared as `int X(...);`. These functions return:
+ * -1 on parameter error (NULLs, bad values etc)
+ * 0 on success
+ * 1 on failure
+ * Thus, one can check success with ret = X(...); if (ret != 0) {panic();}
+ * If a function returns a pointer, NULL is the error value.
+ */
+
+enum read_mode {
+ READS_UNKNOWN = 0,
+ READS_SINGLE = 1,
+ READS_PAIRED = 2,
+ READS_INTERLEAVED = 3,
+};
+
+struct axe_output {
+ struct qes_seqfile *fwd_file;
+ struct qes_seqfile *rev_file;
+ enum read_mode mode;
+};
+
+struct axe_trie {
+ Trie *trie; /* From datrie.h */
+ int mismatch_level;
+ size_t max_len;
+ size_t min_len;
+};
+
+struct axe_barcode {
+ char *seq1;
+ char *seq2;
+ char *id;
+ size_t len1;
+ size_t len2;
+ size_t idlen;
+ uint64_t count;
+};
+
+struct axe_config {
+ char *barcode_file;
+ char *table_file;
+ char *infiles[2];
+ char *out_prefixes[2];
+ struct axe_barcode **barcodes;
+ struct axe_output **outputs;
+ /* Array of output files. Access by bcd_lookup[1st_bcd_idx][2nd_bcd_idx]
+ Values will be 0 <= x < n_barcode_pairs. barcodes or outputs can then
+ be indexed w/ this number */
+ ssize_t **barcode_lookup;
+ size_t *mismatch_counts;
+ size_t n_barcodes_1; /* Number of first read barcodes */
+ size_t n_barcodes_2; /* Number of second read barcodes */
+ size_t n_barcode_pairs;
+ struct axe_output *unknown_output; /* output for unknown files */
+ struct axe_trie *fwd_trie;
+ struct axe_trie *rev_trie;
+ struct qes_logger *logger;
+ enum read_mode in_mode;
+ enum read_mode out_mode;
+ int out_compress_level;
+ size_t mismatches;
+ uint64_t reads_processed;
+ uint64_t reads_demultiplexed;
+ uint64_t reads_failed;
+ float time_taken;
+ int verbosity;
+ int have_cli_opts :1; /* Set to 1 once CLI is parsed */
+ int match_combo :1; /* Match using combinatorial strategy */
+ int permissive :1; /* Don't error on mutated bcd confict */
+ int trim_rev :1; /* Trim rev read same as fwd read */
+ int debug :1; /* Enable debug mode */
+};
+
+extern unsigned int format_call_number;
+
+char *
+axe_formatter(struct qes_log_entry *entry);
+
+#define AXE_LOG_PROGRESS 11
+#define axe_format_progress(log, fmt, ...) \
+ qes_log_format(log, AXE_LOG_PROGRESS, fmt, __VA_ARGS__)
+#define axe_message_progress(log, msg) \
+ qes_log_message(log, AXE_LOG_PROGRESS, msg)
+
+#define AXE_LOG_BOLD 12
+#define axe_format_bold(log, fmt, ...) \
+ qes_log_format(log, AXE_LOG_BOLD, fmt, __VA_ARGS__)
+#define axe_message_bold(log, msg) \
+ qes_log_message(log, AXE_LOG_BOLD, msg)
+
+static inline int
+axe_config_ok(const struct axe_config *config)
+{
+ if (config == NULL) return 0;
+ return 1;
+}
+
+static inline int
+axe_trie_ok(const struct axe_trie *trie)
+{
+ if (trie == NULL) return 0;
+ if (trie->trie == NULL) return 0;
+ if (trie->min_len > trie->max_len) return 0;
+ return 1;
+}
+
+static inline int
+axe_barcode_ok(const struct axe_barcode *barcode)
+{
+ if (barcode == NULL) return 0;
+ if (barcode->seq1 == NULL || barcode->len1 == 0) return 0;
+ if (barcode->id == NULL || barcode->idlen == 0) return 0;
+ return 1;
+}
+
+static inline int
+axe_barcode_ok_combo(const struct axe_barcode *barcode)
+{
+ if (barcode == NULL) return 0;
+ if (barcode->seq1 == NULL || barcode->len1 == 0) return 0;
+ if (barcode->seq2 == NULL || barcode->len2 == 0) return 0;
+ if (barcode->id == NULL || barcode->idlen == 0) return 0;
+ return 1;
+}
+
+static inline int
+axe_output_ok(const struct axe_output *output)
+{
+ if (output == NULL) return 0;
+ if (output->mode == READS_UNKNOWN) return 0;
+ if (output->fwd_file == NULL) return 0;
+ if (output->mode == READS_PAIRED && output->rev_file == NULL) return 0;
+ return 1;
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: axe_config_create
+Paramters: void
+Description: Create a struct axe_config on the heap and initialise members
+ to empty/null values.
+Returns: struct axe_config *: A valid, empty struct axe_config, or NULL
+ on any error.
+ *===========================================================================*/
+struct axe_config *axe_config_create(void);
+
+/*=== FUNCTION ============================================================*
+Name: axe_config_destroy
+Paramters: struct axe_config *: config struct on heap to destroy.
+Description: Destroy a ``struct axe_config`` on the heap, and set its
+ pointer variable to NULL;
+Returns: void
+ *===========================================================================*/
+void axe_config_destroy_(struct axe_config *config);
+#define axe_config_destroy(cfg) STMT_BEGIN \
+ axe_config_destroy_(cfg); \
+ cfg = NULL; \
+ STMT_END
+
+
+/*=== FUNCTION ============================================================*
+Name: axe_output_create
+Paramters: const char *fwd_fpath: Forwards/interleaved read filepath
+ const char *rev_fpath: Reverse read filepath
+ enum read_mode mode: Output mode
+ const char *fp_mode: qes_fopen() mode specifier. See
+ /usr/include/zlib.h for valid values.
+Description: Creates and opens file members of a struct axe_output
+Returns: struct axe_output *: A valid struct axe_output, or NULL on
+ failure of any kind
+ *===========================================================================*/
+struct axe_output *axe_output_create(const char *fwd_fpath,
+ const char *rev_fpath, enum read_mode mode, const char *fp_mode);
+
+/*=== FUNCTION ============================================================*
+Name: axe_output_destroy
+Paramters: struct axe_output *: output struct on heap to destroy.
+Description: Destroy a ``struct axe_output`` on the heap, and set its
+ pointer variable to NULL;
+Returns: void
+ *===========================================================================*/
+void axe_output_destroy_(struct axe_output *output);
+#define axe_output_destroy(out) STMT_BEGIN \
+ axe_output_destroy_(out); \
+ out = NULL; \
+ STMT_END
+
+
+struct axe_trie *axe_trie_create(void);
+extern int axe_trie_get(struct axe_trie *trie, const char *str,
+ intptr_t *data);
+extern int axe_trie_add(struct axe_trie *trie, const char *str,
+ intptr_t data);
+extern int axe_trie_delete(struct axe_trie *trie, const char *str);
+/*=== FUNCTION ============================================================*
+Name: axe_trie_destroy
+Paramters: struct axe_trie *: trie struct on heap to destroy.
+Description: Destroy a ``struct axe_trie`` on the heap, and set its
+ pointer variable to NULL;
+Returns: void
+ *===========================================================================*/
+void axe_trie_destroy_(struct axe_trie *trie);
+#define axe_trie_destroy(trie) STMT_BEGIN \
+ axe_trie_destroy_(trie); \
+ trie = NULL; \
+ STMT_END
+
+
+struct axe_barcode *axe_barcode_create(void);
+void axe_barcode_destroy_(struct axe_barcode *barcode);
+#define axe_barcode_destroy(barcode) STMT_BEGIN \
+ axe_barcode_destroy_(barcode); \
+ barcode = NULL; \
+ STMT_END
+
+
+/* This is the processing pipeline. These functions should be run in this
+ order */
+int axe_read_barcodes(struct axe_config *config);
+int axe_setup_barcode_lookup(struct axe_config *config);
+int axe_make_tries(struct axe_config *config);
+int axe_load_tries(struct axe_config *config);
+int axe_make_outputs(struct axe_config *config);
+int axe_process_file(struct axe_config *config);
+int axe_write_table(const struct axe_config *config);
+int axe_print_summary(const struct axe_config *config);
+
+/* Libraries or inner functions */
+extern int axe_match_read(struct axe_config *config, intptr_t *value,
+ struct axe_trie *trie, const struct qes_seq *seq);
+int product(int64_t len, int64_t elem, uintptr_t *choices, int at_start);
+char **hamming_mutate_dna(size_t *n_results_o, const char *str, size_t len,
+ unsigned int dist, int keep_original);
+
+extern char _time_now[];
+static inline const char *
+nowstr(void)
+{
+ time_t rawtime;
+
+ time(&rawtime);
+ strftime(_time_now, 10, "%H:%M:%S", localtime(&rawtime));
+ return _time_now;
+}
+
+
+#endif /* AXE_H */
diff --git a/src/axe_config.h.in b/src/axe_config.h.in
new file mode 100644
index 0000000..ed20167
--- /dev/null
+++ b/src/axe_config.h.in
@@ -0,0 +1,22 @@
+/*
+ * ============================================================================
+ *
+ * Filename: axe_config.h.in
+ *
+ * Description: Define various things from CMake.
+ *
+ * Created: 15/09/14 14:09:59
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef AXE_CONFIG_H
+#define AXE_CONFIG_H
+
+#define AXE_VERSION "${AXE_VERSION}"
+
+#endif /* AXE_CONFIG_H */
diff --git a/src/datrie/alpha-map-private.h b/src/datrie/alpha-map-private.h
new file mode 100644
index 0000000..017259f
--- /dev/null
+++ b/src/datrie/alpha-map-private.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * alpha-map-private.h - private APIs for alpha-map
+ * Created: 2008-12-04
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __ALPHA_MAP_PRIVATE_H
+#define __ALPHA_MAP_PRIVATE_H
+
+#include <stdio.h>
+#include "alpha-map.h"
+
+TrieIndex alpha_map_char_to_trie (const AlphaMap *alpha_map,
+ AlphaChar ac);
+
+AlphaChar alpha_map_trie_to_char (const AlphaMap *alpha_map,
+ TrieChar tc);
+
+TrieChar * alpha_map_char_to_trie_str (const AlphaMap *alpha_map,
+ const AlphaChar *str);
+
+AlphaChar * alpha_map_trie_to_char_str (const AlphaMap *alpha_map,
+ const TrieChar *str);
+
+
+#endif /* __ALPHA_MAP_PRIVATE_H */
+
+
+/*
+vi:ts=4:ai:expandtab
+*/
+
diff --git a/src/datrie/alpha-map.c b/src/datrie/alpha-map.c
new file mode 100644
index 0000000..863be4a
--- /dev/null
+++ b/src/datrie/alpha-map.c
@@ -0,0 +1,377 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * alpha-map.c - map between character codes and trie alphabet
+ * Created: 2006-08-19
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "alpha-map.h"
+#include "alpha-map-private.h"
+
+/**
+ * @brief Alphabet string length
+ *
+ * @param str : the array of null-terminated AlphaChar string to measure
+ *
+ * @return the total characters in @a str.
+ */
+int
+alpha_char_strlen (const AlphaChar *str)
+{
+ const AlphaChar *p;
+
+ for (p = str; *p; p++)
+ ;
+ return p - str;
+}
+
+/**
+ * @brief Compare alphabet strings
+ *
+ * @param str1, str2 : the arrays of null-terminated AlphaChar strings
+ * to compare
+ *
+ * @return negative if @a str1 < @a str2;
+ * 0 if @a str1 == @a str2;
+ * positive if @a str1 > @a str2
+ *
+ * Available since: 0.2.7
+ */
+int
+alpha_char_strcmp (const AlphaChar *str1, const AlphaChar *str2)
+{
+ while (*str1 && *str1 == *str2) {
+ str1++; str2++;
+ }
+ if (*str1 < *str2)
+ return -1;
+ if (*str1 > *str2)
+ return 1;
+ return 0;
+}
+
+/*------------------------------*
+ * PRIVATE DATA DEFINITONS *
+ *------------------------------*/
+
+typedef struct _AlphaRange {
+ struct _AlphaRange *next;
+
+ AlphaChar begin;
+ AlphaChar end;
+} AlphaRange;
+
+struct _AlphaMap {
+ AlphaRange *first_range;
+};
+
+/*-----------------------------*
+ * METHODS IMPLEMENTAIONS *
+ *-----------------------------*/
+
+#define ALPHAMAP_SIGNATURE 0xD9FCD9FC
+
+/* AlphaMap Header:
+ * - INT32: signature
+ * - INT32: total ranges
+ *
+ * Ranges:
+ * - INT32: range begin
+ * - INT32: range end
+ */
+
+/**
+ * @brief Create new alphabet map
+ *
+ * @return a pointer to the newly created alphabet map, NULL on failure
+ *
+ * Create a new empty alphabet map. The map contents can then be added with
+ * alpha_map_add_range().
+ *
+ * The created object must be freed with alpha_map_free().
+ */
+AlphaMap *
+alpha_map_new (void)
+{
+ AlphaMap *alpha_map;
+
+ alpha_map = (AlphaMap *) malloc (sizeof (AlphaMap));
+ if (!alpha_map)
+ return NULL;
+
+ alpha_map->first_range = NULL;
+
+ return alpha_map;
+}
+
+/**
+ * @brief Create a clone of alphabet map
+ *
+ * @param a_map : the source alphabet map to clone
+ *
+ * @return a pointer to the alphabet map clone, NULL on failure
+ *
+ * The created object must be freed with alpha_map_free().
+ */
+AlphaMap *
+alpha_map_clone (const AlphaMap *a_map)
+{
+ AlphaMap *alpha_map;
+ AlphaRange *range;
+
+ alpha_map = alpha_map_new ();
+ if (!alpha_map)
+ return NULL;
+
+ for (range = a_map->first_range; range; range = range->next) {
+ if (alpha_map_add_range (alpha_map, range->begin, range->end) != 0) {
+ alpha_map_free (alpha_map);
+ return NULL;
+ }
+ }
+
+ return alpha_map;
+}
+
+/**
+ * @brief Free an alphabet map object
+ *
+ * @param alpha_map : the alphabet map object to free
+ *
+ * Destruct the @a alpha_map and free its allocated memory.
+ */
+void
+alpha_map_free (AlphaMap *alpha_map)
+{
+ AlphaRange *p, *q;
+
+ p = alpha_map->first_range;
+ while (p) {
+ q = p->next;
+ free (p);
+ p = q;
+ }
+
+ free (alpha_map);
+}
+
+/**
+ * @brief Add a range to alphabet map
+ *
+ * @param alpha_map : the alphabet map object
+ * @param begin : the first character of the range
+ * @param end : the last character of the range
+ *
+ * @return 0 on success, non-zero on failure
+ *
+ * Add a range of character codes from @a begin to @a end to the
+ * alphabet set.
+ */
+int
+alpha_map_add_range (AlphaMap *alpha_map, AlphaChar begin, AlphaChar end)
+{
+ AlphaRange *q, *r, *begin_node, *end_node;
+
+ if (begin > end)
+ return -1;
+
+ begin_node = end_node = 0;
+
+ /* Skip first ranges till 'begin' is covered */
+ for (q = 0, r = alpha_map->first_range;
+ r && r->begin <= begin;
+ q = r, r = r->next)
+ {
+ if (begin <= r->end) {
+ /* 'r' covers 'begin' -> take 'r' as beginning point */
+ begin_node = r;
+ break;
+ }
+ if (r->end + 1 == begin) {
+ /* 'begin' is next to 'r'-end
+ * -> extend 'r'-end to cover 'begin'
+ */
+ r->end = begin;
+ begin_node = r;
+ break;
+ }
+ }
+ if (!begin_node && r && r->begin <= end + 1) {
+ /* ['begin', 'end'] overlaps into 'r'-begin
+ * or 'r' is next to 'end' if r->begin == end + 1
+ * -> extend 'r'-begin to include the range
+ */
+ r->begin = begin;
+ begin_node = r;
+ }
+ /* Run upto the first range that exceeds 'end' */
+ while (r && r->begin <= end + 1) {
+ if (end <= r->end) {
+ /* 'r' covers 'end' -> take 'r' as ending point */
+ end_node = r;
+ } else if (r != begin_node) {
+ /* ['begin', 'end'] covers the whole 'r' -> remove 'r' */
+ if (q) {
+ q->next = r->next;
+ free (r);
+ r = q->next;
+ } else {
+ alpha_map->first_range = r->next;
+ free (r);
+ r = alpha_map->first_range;
+ }
+ continue;
+ }
+ q = r;
+ r = r->next;
+ }
+ if (!end_node && q && begin <= q->end) {
+ /* ['begin', 'end'] overlaps 'q' at the end
+ * -> extend 'q'-end to include the range
+ */
+ q->end = end;
+ end_node = q;
+ }
+
+ if (begin_node && end_node) {
+ if (begin_node != end_node) {
+ /* Merge begin_node and end_node ranges together */
+ assert (begin_node->next == end_node);
+ begin_node->end = end_node->end;
+ begin_node->next = end_node->next;
+ free (end_node);
+ }
+ } else if (!begin_node && !end_node) {
+ /* ['begin', 'end'] overlaps with none of the ranges
+ * -> insert a new range
+ */
+ AlphaRange *range = (AlphaRange *) malloc (sizeof (AlphaRange));
+
+ if (!range)
+ return -1;
+
+ range->begin = begin;
+ range->end = end;
+
+ /* insert it between 'q' and 'r' */
+ if (q) {
+ q->next = range;
+ } else {
+ alpha_map->first_range = range;
+ }
+ range->next = r;
+ }
+
+ return 0;
+}
+
+TrieIndex
+alpha_map_char_to_trie (const AlphaMap *alpha_map, AlphaChar ac)
+{
+ TrieIndex alpha_begin;
+ AlphaRange *range;
+
+ if (0 == ac)
+ return 0;
+
+ alpha_begin = 1;
+ for (range = alpha_map->first_range; range; range = range->next) {
+ if (range->begin <= ac && ac <= range->end)
+ return alpha_begin + (ac - range->begin);
+
+ alpha_begin += range->end - range->begin + 1;
+ }
+
+ return TRIE_INDEX_MAX;
+}
+
+AlphaChar
+alpha_map_trie_to_char (const AlphaMap *alpha_map, TrieChar tc)
+{
+ TrieChar alpha_begin;
+ AlphaRange *range;
+
+ if (0 == tc)
+ return 0;
+
+ alpha_begin = 1;
+ for (range = alpha_map->first_range; range; range = range->next) {
+ if (tc <= alpha_begin + (range->end - range->begin))
+ return range->begin + (tc - alpha_begin);
+
+ alpha_begin += range->end - range->begin + 1;
+ }
+
+ return ALPHA_CHAR_ERROR;
+}
+
+TrieChar *
+alpha_map_char_to_trie_str (const AlphaMap *alpha_map, const AlphaChar *str)
+{
+ TrieChar *trie_str, *p;
+
+ trie_str = (TrieChar *) malloc (alpha_char_strlen (str) + 1);
+ if (!trie_str)
+ return NULL;
+
+ for (p = trie_str; *str; p++, str++) {
+ TrieIndex tc = alpha_map_char_to_trie (alpha_map, *str);
+ if (TRIE_INDEX_MAX == tc)
+ goto error_str_allocated;
+ *p = (TrieChar) tc;
+ }
+ *p = 0;
+
+ return trie_str;
+
+error_str_allocated:
+ free (trie_str);
+ return NULL;
+}
+
+AlphaChar *
+alpha_map_trie_to_char_str (const AlphaMap *alpha_map, const TrieChar *str)
+{
+ AlphaChar *alpha_str, *p;
+
+ alpha_str = (AlphaChar *) malloc ((strlen ((const char *)str) + 1)
+ * sizeof (AlphaChar));
+ if (!alpha_str)
+ return NULL;
+
+ for (p = alpha_str; *str; p++, str++) {
+ *p = (AlphaChar) alpha_map_trie_to_char (alpha_map, *str);
+ }
+ *p = 0;
+
+ return alpha_str;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/alpha-map.h b/src/datrie/alpha-map.h
new file mode 100644
index 0000000..63b61f1
--- /dev/null
+++ b/src/datrie/alpha-map.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * alpha-map.h - map between character codes and trie alphabet
+ * Created: 2006-08-19
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __ALPHA_MAP_H
+#define __ALPHA_MAP_H
+
+#include <stdio.h>
+
+#include "typedefs.h"
+#include "triedefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file alpha-map.h
+ * @brief AlphaMap data type and functions
+ *
+ * AlphaMap is a mapping between AlphaChar and TrieChar. AlphaChar is the
+ * alphabet character used in words of a target language, while TrieChar
+ * is a small integer with packed range of values and is actually used in
+ * trie state transition calculations.
+ *
+ * Since double-array trie relies on sparse state transition table,
+ * a small set of input characters can make the table small, i.e. with
+ * small number of columns. But in real life, alphabet characters can be
+ * of non-continuous range of values. The unused slots between them can
+ * waste the space in the table, and can increase the chance of unused
+ * array cells.
+ *
+ * AlphaMap is thus defined for mapping between non-continuous ranges of
+ * values of AlphaChar and packed and continuous range of Triechar.
+ *
+ * In this implementation, TrieChar is defined as a single-byte integer,
+ * which means the largest AlphaChar set that is supported is of 255
+ * values, as the special value of 0 is reserved for null-termination code.
+ */
+
+/**
+ * @brief AlphaMap data type
+ */
+typedef struct _AlphaMap AlphaMap;
+
+AlphaMap * alpha_map_new (void);
+
+AlphaMap * alpha_map_clone (const AlphaMap *a_map);
+
+void alpha_map_free (AlphaMap *alpha_map);
+
+int alpha_map_add_range (AlphaMap *alpha_map,
+ AlphaChar begin,
+ AlphaChar end);
+
+int alpha_char_strlen (const AlphaChar *str);
+int alpha_char_strcmp (const AlphaChar *str1, const AlphaChar *str2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALPHA_MAP_H */
+
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/darray.c b/src/datrie/darray.c
new file mode 100644
index 0000000..f07c218
--- /dev/null
+++ b/src/datrie/darray.c
@@ -0,0 +1,757 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * darray.c - Double-array trie structure
+ * Created: 2006-08-13
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#ifndef _MSC_VER /* for SIZE_MAX */
+# include <stdint.h>
+#endif
+#include <stdio.h>
+
+#include "trie-private.h"
+#include "darray.h"
+
+/*----------------------------------*
+ * INTERNAL TYPES DECLARATIONS *
+ *----------------------------------*/
+
+struct _Symbols {
+ short num_symbols;
+ TrieChar symbols[256];
+};
+
+#define symbols_add_fast(s,c) ((s)->symbols[(s)->num_symbols++] = c)
+
+/*-----------------------------------*
+ * PRIVATE METHODS DECLARATIONS *
+ *-----------------------------------*/
+
+#define da_get_free_list(d) (1)
+
+static bool da_check_free_cell (DArray *d,
+ TrieIndex s);
+
+static bool da_has_children (const DArray *d,
+ TrieIndex s);
+
+static TrieIndex da_find_free_base (DArray *d,
+ const Symbols *symbols);
+
+static bool da_fit_symbols (DArray *d,
+ TrieIndex base,
+ const Symbols *symbols);
+
+static void da_relocate_base (DArray *d,
+ TrieIndex s,
+ TrieIndex new_base);
+
+static bool da_extend_pool (DArray *d,
+ TrieIndex to_index);
+
+static void da_alloc_cell (DArray *d,
+ TrieIndex cell);
+
+static void da_free_cell (DArray *d,
+ TrieIndex cell);
+
+/* ==================== BEGIN IMPLEMENTATION PART ==================== */
+
+/*------------------------------------*
+ * INTERNAL TYPES IMPLEMENTATIONS *
+ *------------------------------------*/
+
+Symbols *
+symbols_new (void)
+{
+ Symbols *syms;
+
+ syms = (Symbols *) malloc (sizeof (Symbols));
+
+ if (!syms)
+ return NULL;
+
+ syms->num_symbols = 0;
+
+ return syms;
+}
+
+void
+symbols_free (Symbols *syms)
+{
+ free (syms);
+}
+
+void
+symbols_add (Symbols *syms, TrieChar c)
+{
+ short lower, upper;
+
+ lower = 0;
+ upper = syms->num_symbols;
+ while (lower < upper) {
+ short middle;
+
+ middle = (lower + upper)/2;
+ if (c > syms->symbols[middle])
+ lower = middle + 1;
+ else if (c < syms->symbols[middle])
+ upper = middle;
+ else
+ return;
+ }
+ if (lower < syms->num_symbols) {
+ memmove (syms->symbols + lower + 1, syms->symbols + lower,
+ syms->num_symbols - lower);
+ }
+ syms->symbols[lower] = c;
+ syms->num_symbols++;
+}
+
+int
+symbols_num (const Symbols *syms)
+{
+ return syms->num_symbols;
+}
+
+TrieChar
+symbols_get (const Symbols *syms, int index)
+{
+ return syms->symbols[index];
+}
+
+
+/*------------------------------*
+ * PRIVATE DATA DEFINITONS *
+ *------------------------------*/
+
+typedef struct {
+ TrieIndex base;
+ TrieIndex check;
+} DACell;
+
+struct _DArray {
+ TrieIndex num_cells;
+ DACell *cells;
+};
+
+/*-----------------------------*
+ * METHODS IMPLEMENTAIONS *
+ *-----------------------------*/
+
+#define DA_SIGNATURE 0xDAFCDAFC
+
+/* DA Header:
+ * - Cell 0: SIGNATURE, number of cells
+ * - Cell 1: free circular-list pointers
+ * - Cell 2: root node
+ * - Cell 3: DA pool begin
+ */
+#define DA_POOL_BEGIN 3
+
+/**
+ * @brief Create a new double-array object
+ *
+ * Create a new empty doubla-array object.
+ */
+DArray *
+da_new (void)
+{
+ DArray *d;
+
+ d = (DArray *) malloc (sizeof (DArray));
+ if (!d)
+ return NULL;
+
+ d->num_cells = DA_POOL_BEGIN;
+ d->cells = (DACell *) malloc (d->num_cells * sizeof (DACell));
+ if (!d->cells)
+ goto exit_da_created;
+ d->cells[0].base = DA_SIGNATURE;
+ d->cells[0].check = d->num_cells;
+ d->cells[1].base = -1;
+ d->cells[1].check = -1;
+ d->cells[2].base = DA_POOL_BEGIN;
+ d->cells[2].check = 0;
+
+ return d;
+
+exit_da_created:
+ free (d);
+ return NULL;
+}
+
+/**
+ * @brief Free double-array data
+ *
+ * @param d : the double-array data
+ *
+ * Free the given double-array data.
+ */
+void
+da_free (DArray *d)
+{
+ free (d->cells);
+ free (d);
+}
+
+
+/**
+ * @brief Get root state
+ *
+ * @param d : the double-array data
+ *
+ * @return root state of the @a index set, or TRIE_INDEX_ERROR on failure
+ *
+ * Get root state for stepwise walking.
+ */
+TrieIndex
+da_get_root (const DArray *d)
+{
+ (void) d;
+ /* can be calculated value for multi-index trie */
+ return 2;
+}
+
+
+/**
+ * @brief Get BASE cell
+ *
+ * @param d : the double-array data
+ * @param s : the double-array state to get data
+ *
+ * @return the BASE cell value for the given state
+ *
+ * Get BASE cell value for the given state.
+ */
+TrieIndex
+da_get_base (const DArray *d, TrieIndex s)
+{
+ return (s < d->num_cells) ? d->cells[s].base : TRIE_INDEX_ERROR;
+}
+
+/**
+ * @brief Get CHECK cell
+ *
+ * @param d : the double-array data
+ * @param s : the double-array state to get data
+ *
+ * @return the CHECK cell value for the given state
+ *
+ * Get CHECK cell value for the given state.
+ */
+TrieIndex
+da_get_check (const DArray *d, TrieIndex s)
+{
+ return (s < d->num_cells) ? d->cells[s].check : TRIE_INDEX_ERROR;
+}
+
+
+/**
+ * @brief Set BASE cell
+ *
+ * @param d : the double-array data
+ * @param s : the double-array state to get data
+ * @param val : the value to set
+ *
+ * Set BASE cell for the given state to the given value.
+ */
+void
+da_set_base (DArray *d, TrieIndex s, TrieIndex val)
+{
+ if (s < d->num_cells) {
+ d->cells[s].base = val;
+ }
+}
+
+/**
+ * @brief Set CHECK cell
+ *
+ * @param d : the double-array data
+ * @param s : the double-array state to get data
+ * @param val : the value to set
+ *
+ * Set CHECK cell for the given state to the given value.
+ */
+void
+da_set_check (DArray *d, TrieIndex s, TrieIndex val)
+{
+ if (s < d->num_cells) {
+ d->cells[s].check = val;
+ }
+}
+
+/**
+ * @brief Walk in double-array structure
+ *
+ * @param d : the double-array structure
+ * @param s : current state
+ * @param c : the input character
+ *
+ * @return boolean indicating success
+ *
+ * Walk the double-array trie from state @a *s, using input character @a c.
+ * If there exists an edge from @a *s with arc labeled @a c, this function
+ * returns true and @a *s is updated to the new state. Otherwise, it returns
+ * false and @a *s is left unchanged.
+ */
+bool
+da_walk (const DArray *d, TrieIndex *s, TrieChar c)
+{
+ TrieIndex next;
+
+ next = da_get_base (d, *s) + c;
+ if (da_get_check (d, next) == *s) {
+ *s = next;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Insert a branch from trie node
+ *
+ * @param d : the double-array structure
+ * @param s : the state to add branch to
+ * @param c : the character for the branch label
+ *
+ * @return the index of the new node
+ *
+ * Insert a new arc labelled with character @a c from the trie node
+ * represented by index @a s in double-array structure @a d.
+ * Note that it assumes that no such arc exists before inserting.
+ */
+TrieIndex
+da_insert_branch (DArray *d, TrieIndex s, TrieChar c)
+{
+ TrieIndex base, next;
+
+ base = da_get_base (d, s);
+
+ if (base > 0) {
+ next = base + c;
+
+ /* if already there, do not actually insert */
+ if (da_get_check (d, next) == s)
+ return next;
+
+ /* if (base + c) > TRIE_INDEX_MAX which means 'next' is overflow,
+ * or cell [next] is not free, relocate to a free slot
+ */
+ if (base > TRIE_INDEX_MAX - c || !da_check_free_cell (d, next)) {
+ Symbols *symbols;
+ TrieIndex new_base;
+
+ /* relocate BASE[s] */
+ symbols = da_output_symbols (d, s);
+ symbols_add (symbols, c);
+ new_base = da_find_free_base (d, symbols);
+ symbols_free (symbols);
+
+ if (TRIE_INDEX_ERROR == new_base)
+ return TRIE_INDEX_ERROR;
+
+ da_relocate_base (d, s, new_base);
+ next = new_base + c;
+ }
+ } else {
+ Symbols *symbols;
+ TrieIndex new_base;
+
+ symbols = symbols_new ();
+ symbols_add (symbols, c);
+ new_base = da_find_free_base (d, symbols);
+ symbols_free (symbols);
+
+ if (TRIE_INDEX_ERROR == new_base)
+ return TRIE_INDEX_ERROR;
+
+ da_set_base (d, s, new_base);
+ next = new_base + c;
+ }
+ da_alloc_cell (d, next);
+ da_set_check (d, next, s);
+
+ return next;
+}
+
+static bool
+da_check_free_cell (DArray *d,
+ TrieIndex s)
+{
+ return da_extend_pool (d, s) && da_get_check (d, s) < 0;
+}
+
+static bool
+da_has_children (const DArray *d,
+ TrieIndex s)
+{
+ TrieIndex base;
+ TrieIndex c, max_c;
+
+ base = da_get_base (d, s);
+ if (TRIE_INDEX_ERROR == base || base < 0)
+ return false;
+
+ max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - base);
+ for (c = 0; c <= max_c; c++) {
+ if (da_get_check (d, base + c) == s)
+ return true;
+ }
+
+ return false;
+}
+
+Symbols *
+da_output_symbols (const DArray *d,
+ TrieIndex s)
+{
+ Symbols *syms;
+ TrieIndex base;
+ TrieIndex c, max_c;
+
+ syms = symbols_new ();
+
+ base = da_get_base (d, s);
+ max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - base);
+ for (c = 0; c <= max_c; c++) {
+ if (da_get_check (d, base + c) == s)
+ symbols_add_fast (syms, (TrieChar) c);
+ }
+
+ return syms;
+}
+
+static TrieIndex
+da_find_free_base (DArray *d,
+ const Symbols *symbols)
+{
+ TrieChar first_sym;
+ TrieIndex s;
+
+ /* find first free cell that is beyond the first symbol */
+ first_sym = symbols_get (symbols, 0);
+ s = -da_get_check (d, da_get_free_list (d));
+ while (s != da_get_free_list (d)
+ && s < (TrieIndex) first_sym + DA_POOL_BEGIN)
+ {
+ s = -da_get_check (d, s);
+ }
+ if (s == da_get_free_list (d)) {
+ for (s = first_sym + DA_POOL_BEGIN; ; ++s) {
+ if (!da_extend_pool (d, s))
+ return TRIE_INDEX_ERROR;
+ if (da_get_check (d, s) < 0)
+ break;
+ }
+ }
+
+ /* search for next free cell that fits the symbols set */
+ while (!da_fit_symbols (d, s - first_sym, symbols)) {
+ /* extend pool before getting exhausted */
+ if (-da_get_check (d, s) == da_get_free_list (d)) {
+ if (!da_extend_pool (d, d->num_cells))
+ return TRIE_INDEX_ERROR;
+ }
+
+ s = -da_get_check (d, s);
+ }
+
+ return s - first_sym;
+}
+
+static bool
+da_fit_symbols (DArray *d,
+ TrieIndex base,
+ const Symbols *symbols)
+{
+ int i;
+
+ for (i = 0; i < symbols_num (symbols); i++) {
+ TrieChar sym = symbols_get (symbols, i);
+
+ /* if (base + sym) > TRIE_INDEX_MAX which means it's overflow,
+ * or cell [base + sym] is not free, the symbol is not fit.
+ */
+ if (base > TRIE_INDEX_MAX - sym || !da_check_free_cell (d, base + sym))
+ return false;
+ }
+ return true;
+}
+
+static void
+da_relocate_base (DArray *d,
+ TrieIndex s,
+ TrieIndex new_base)
+{
+ TrieIndex old_base;
+ Symbols *symbols;
+ int i;
+
+ old_base = da_get_base (d, s);
+ symbols = da_output_symbols (d, s);
+
+ for (i = 0; i < symbols_num (symbols); i++) {
+ TrieIndex old_next, new_next, old_next_base;
+
+ old_next = old_base + symbols_get (symbols, i);
+ new_next = new_base + symbols_get (symbols, i);
+ old_next_base = da_get_base (d, old_next);
+
+ /* allocate new next node and copy BASE value */
+ da_alloc_cell (d, new_next);
+ da_set_check (d, new_next, s);
+ da_set_base (d, new_next, old_next_base);
+
+ /* old_next node is now moved to new_next
+ * so, all cells belonging to old_next
+ * must be given to new_next
+ */
+ /* preventing the case of TAIL pointer */
+ if (old_next_base > 0) {
+ TrieIndex c, max_c;
+
+ max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - old_next_base);
+ for (c = 0; c <= max_c; c++) {
+ if (da_get_check (d, old_next_base + c) == old_next)
+ da_set_check (d, old_next_base + c, new_next);
+ }
+ }
+
+ /* free old_next node */
+ da_free_cell (d, old_next);
+ }
+
+ symbols_free (symbols);
+
+ /* finally, make BASE[s] point to new_base */
+ da_set_base (d, s, new_base);
+}
+
+static bool
+da_extend_pool (DArray *d,
+ TrieIndex to_index)
+{
+ TrieIndex new_begin;
+ TrieIndex i;
+ TrieIndex free_tail;
+
+ if (to_index <= 0 || TRIE_INDEX_MAX <= to_index)
+ return false;
+
+ if (to_index < d->num_cells)
+ return true;
+
+ d->cells = (DACell *) realloc (d->cells, (to_index + 1) * sizeof (DACell));
+ new_begin = d->num_cells;
+ d->num_cells = to_index + 1;
+
+ /* initialize new free list */
+ for (i = new_begin; i < to_index; i++) {
+ da_set_check (d, i, -(i + 1));
+ da_set_base (d, i + 1, -i);
+ }
+
+ /* merge the new circular list to the old */
+ free_tail = -da_get_base (d, da_get_free_list (d));
+ da_set_check (d, free_tail, -new_begin);
+ da_set_base (d, new_begin, -free_tail);
+ da_set_check (d, to_index, -da_get_free_list (d));
+ da_set_base (d, da_get_free_list (d), -to_index);
+
+ /* update header cell */
+ d->cells[0].check = d->num_cells;
+
+ return true;
+}
+
+/**
+ * @brief Prune the single branch
+ *
+ * @param d : the double-array structure
+ * @param s : the dangling state to prune off
+ *
+ * Prune off a non-separate path up from the final state @a s.
+ * If @a s still has some children states, it does nothing. Otherwise,
+ * it deletes the node and all its parents which become non-separate.
+ */
+void
+da_prune (DArray *d, TrieIndex s)
+{
+ da_prune_upto (d, da_get_root (d), s);
+}
+
+/**
+ * @brief Prune the single branch up to given parent
+ *
+ * @param d : the double-array structure
+ * @param p : the parent up to which to be pruned
+ * @param s : the dangling state to prune off
+ *
+ * Prune off a non-separate path up from the final state @a s to the
+ * given parent @a p. The prunning stop when either the parent @a p
+ * is met, or a first non-separate node is found.
+ */
+void
+da_prune_upto (DArray *d, TrieIndex p, TrieIndex s)
+{
+ while (p != s && !da_has_children (d, s)) {
+ TrieIndex parent;
+
+ parent = da_get_check (d, s);
+ da_free_cell (d, s);
+ s = parent;
+ }
+}
+
+static void
+da_alloc_cell (DArray *d,
+ TrieIndex cell)
+{
+ TrieIndex prev, next;
+
+ prev = -da_get_base (d, cell);
+ next = -da_get_check (d, cell);
+
+ /* remove the cell from free list */
+ da_set_check (d, prev, -next);
+ da_set_base (d, next, -prev);
+}
+
+static void
+da_free_cell (DArray *d,
+ TrieIndex cell)
+{
+ TrieIndex i, prev;
+
+ /* find insertion point */
+ i = -da_get_check (d, da_get_free_list (d));
+ while (i != da_get_free_list (d) && i < cell)
+ i = -da_get_check (d, i);
+
+ prev = -da_get_base (d, i);
+
+ /* insert cell before i */
+ da_set_check (d, cell, -i);
+ da_set_base (d, cell, -prev);
+ da_set_check (d, prev, -cell);
+ da_set_base (d, i, -cell);
+}
+
+/**
+ * @brief Find first separate node in a sub-trie
+ *
+ * @param d : the double-array structure
+ * @param root : the sub-trie root to search from
+ * @param keybuff : the TrieString buffer for incrementally calcuating key
+ *
+ * @return index to the first separate node; TRIE_INDEX_ERROR on any failure
+ *
+ * Find the first separate node under a sub-trie rooted at @a root.
+ *
+ * On return, @a keybuff is appended with the key characters which walk from
+ * @a root to the separate node. This is for incrementally calculating the
+ * transition key, which is more efficient than later totally reconstructing
+ * key from the given separate node.
+ *
+ * Available since: 0.2.6
+ */
+TrieIndex
+da_first_separate (DArray *d, TrieIndex root, TrieString *keybuff)
+{
+ TrieIndex base;
+ TrieIndex c, max_c;
+
+ while ((base = da_get_base (d, root)) >= 0) {
+ max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - base);
+ for (c = 0; c <= max_c; c++) {
+ if (da_get_check (d, base + c) == root)
+ break;
+ }
+
+ if (c == max_c)
+ return TRIE_INDEX_ERROR;
+
+ trie_string_append_char (keybuff, c);
+ root = base + c;
+ }
+
+ return root;
+}
+
+/**
+ * @brief Find next separate node in a sub-trie
+ *
+ * @param d : the double-array structure
+ * @param root : the sub-trie root to search from
+ * @param sep : the current separate node
+ * @param keybuff : the TrieString buffer for incrementally calcuating key
+ *
+ * @return index to the next separate node; TRIE_INDEX_ERROR if no more
+ * separate node is found
+ *
+ * Find the next separate node under a sub-trie rooted at @a root starting
+ * from the current separate node @a sep.
+ *
+ * On return, @a keybuff is incrementally updated from the key which walks
+ * to previous separate node to the one which walks to the new separate node.
+ * So, it is assumed to be initialized by at least one da_first_separate()
+ * call before. This incremental key calculation is more efficient than later
+ * totally reconstructing key from the given separate node.
+ *
+ * Available since: 0.2.6
+ */
+TrieIndex
+da_next_separate (DArray *d, TrieIndex root, TrieIndex sep, TrieString *keybuff)
+{
+ TrieIndex parent;
+ TrieIndex base;
+ TrieIndex c, max_c;
+
+ while (sep != root) {
+ parent = da_get_check (d, sep);
+ base = da_get_base (d, parent);
+ c = sep - base;
+
+ trie_string_cut_last (keybuff);
+
+ /* find next sibling of sep */
+ max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - base);
+ while (++c <= max_c) {
+ if (da_get_check (d, base + c) == parent) {
+ trie_string_append_char (keybuff, c);
+ return da_first_separate (d, base + c, keybuff);
+ }
+ }
+
+ sep = parent;
+ }
+
+ return TRIE_INDEX_ERROR;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/darray.h b/src/datrie/darray.h
new file mode 100644
index 0000000..4cf1d94
--- /dev/null
+++ b/src/datrie/darray.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * darray.h - Double-array trie structure
+ * Created: 2006-08-11
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __DARRAY_H
+#define __DARRAY_H
+
+#include "triedefs.h"
+#include "trie-string.h"
+
+/**
+ * @file darray.h
+ * @brief Double-array trie structure
+ */
+
+/**
+ * @brief Symbol set structure type
+ */
+typedef struct _Symbols Symbols;
+
+Symbols * symbols_new (void);
+void symbols_free (Symbols *syms);
+void symbols_add (Symbols *syms, TrieChar c);
+int symbols_num (const Symbols *syms);
+TrieChar symbols_get (const Symbols *syms, int index);
+
+/**
+ * @brief Double-array structure type
+ */
+typedef struct _DArray DArray;
+
+
+DArray * da_new (void);
+
+void da_free (DArray *d);
+
+TrieIndex da_get_root (const DArray *d);
+
+
+TrieIndex da_get_base (const DArray *d, TrieIndex s);
+
+TrieIndex da_get_check (const DArray *d, TrieIndex s);
+
+
+void da_set_base (DArray *d, TrieIndex s, TrieIndex val);
+
+void da_set_check (DArray *d, TrieIndex s, TrieIndex val);
+
+bool da_walk (const DArray *d, TrieIndex *s, TrieChar c);
+
+Symbols * da_output_symbols (const DArray *d, TrieIndex s);
+
+/**
+ * @brief Test walkability in double-array structure
+ *
+ * @param d : the double-array structure
+ * @param s : current state
+ * @param c : the input character
+ *
+ * @return boolean indicating walkability
+ *
+ * Test if there is a transition from state @a s with input character @a c.
+ */
+/*
+bool da_is_walkable (DArray *d, TrieIndex s, TrieChar c);
+*/
+#define da_is_walkable(d,s,c) \
+ (da_get_check ((d), da_get_base ((d), (s)) + (c)) == (s))
+
+TrieIndex da_insert_branch (DArray *d, TrieIndex s, TrieChar c);
+
+void da_prune (DArray *d, TrieIndex s);
+
+void da_prune_upto (DArray *d, TrieIndex p, TrieIndex s);
+
+TrieIndex da_first_separate (DArray *d, TrieIndex root, TrieString *keybuff);
+
+TrieIndex da_next_separate (DArray *d,
+ TrieIndex root,
+ TrieIndex sep,
+ TrieString *keybuff);
+
+#endif /* __DARRAY_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/dstring-private.h b/src/datrie/dstring-private.h
new file mode 100644
index 0000000..517bbf5
--- /dev/null
+++ b/src/datrie/dstring-private.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * dstring-private.h - Dynamic string type
+ * Created: 2012-08-02
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __DSTRING_PRIVATE_H
+#define __DSTRING_PRIVATE_H
+
+#include "typedefs.h"
+
+
+struct _DString {
+ int char_size;
+ int str_len;
+ int alloc_size;
+ void * val;
+};
+
+
+#endif /* __DSTRING_PRIVATE_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/dstring.c b/src/datrie/dstring.c
new file mode 100644
index 0000000..e80c25a
--- /dev/null
+++ b/src/datrie/dstring.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * dstring.c - Dynamic string type
+ * Created: 2012-08-01
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include "dstring.h"
+#include "dstring-private.h"
+
+#include "trie-private.h"
+#include <string.h>
+#include <stdlib.h>
+
+
+DString *
+dstring_new (int char_size, int n_elm)
+{
+ DString *ds;
+
+ ds = (DString *) malloc (sizeof (DString));
+ if (!ds)
+ return NULL;
+
+ ds->alloc_size = char_size * n_elm;
+ ds->val = malloc (ds->alloc_size);
+ if (!ds->val) {
+ free (ds);
+ return NULL;
+ }
+
+ ds->char_size = char_size;
+ ds->str_len = 0;
+
+ return ds;
+}
+
+void
+dstring_free (DString *ds)
+{
+ free (ds->val);
+ free (ds);
+}
+
+int
+dstring_length (const DString *ds)
+{
+ return ds->str_len;
+}
+
+const void *
+dstring_get_val (const DString *ds)
+{
+ return ds->val;
+}
+
+void *
+dstring_get_val_rw (DString *ds)
+{
+ return ds->val;
+}
+
+void
+dstring_clear (DString *ds)
+{
+ ds->str_len = 0;
+}
+
+static bool
+dstring_ensure_space (DString *ds, int size)
+{
+ if (ds->alloc_size < size) {
+ int re_size = MAX_VAL (ds->alloc_size * 2, size);
+ void *re_ptr = realloc (ds->val, re_size);
+ if (!re_ptr)
+ return false;
+ ds->val = re_ptr;
+ ds->alloc_size = re_size;
+ }
+
+ return true;
+}
+
+bool
+dstring_copy (DString *dst, const DString *src)
+{
+ if (!dstring_ensure_space (dst, (src->str_len + 1) * src->char_size))
+ return false;
+
+ memcpy (dst->val, src->val, (src->str_len + 1) * src->char_size);
+
+ dst->char_size = src->char_size;
+ dst->str_len = src->str_len;
+
+ return true;
+}
+
+bool
+dstring_append (DString *dst, const DString *src)
+{
+ if (dst->char_size != src->char_size)
+ return false;
+
+ if (!dstring_ensure_space (dst, (dst->str_len + src->str_len + 1)
+ * dst->char_size))
+ {
+ return false;
+ }
+
+ memcpy ((char *)dst->val + (dst->char_size * dst->str_len), src->val,
+ (src->str_len + 1) * dst->char_size);
+
+ dst->str_len += src->str_len;
+
+ return true;
+}
+
+bool
+dstring_append_string (DString *ds, const void *data, int len)
+{
+ if (!dstring_ensure_space (ds, (ds->str_len + len + 1) * ds->char_size))
+ return false;
+
+ memcpy ((char *)ds->val + (ds->char_size * ds->str_len), data,
+ ds->char_size * len);
+
+ ds->str_len += len;
+
+ return true;
+}
+
+bool
+dstring_append_char (DString *ds, const void *data)
+{
+ if (!dstring_ensure_space (ds, (ds->str_len + 2) * ds->char_size))
+ return false;
+
+ memcpy ((char *)ds->val + (ds->char_size * ds->str_len), data,
+ ds->char_size);
+
+ ds->str_len++;
+
+ return true;
+}
+
+bool
+dstring_terminate (DString *ds)
+{
+ if (!dstring_ensure_space (ds, (ds->str_len + 2) * ds->char_size))
+ return false;
+
+ memset ((char *)ds->val + (ds->char_size * ds->str_len), 0, ds->char_size);
+
+ return true;
+}
+
+bool
+dstring_cut_last (DString *ds)
+{
+ if (0 == ds->str_len)
+ return false;
+
+ ds->str_len--;
+
+ return true;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/dstring.h b/src/datrie/dstring.h
new file mode 100644
index 0000000..e700237
--- /dev/null
+++ b/src/datrie/dstring.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * dstring.h - Dynamic string type
+ * Created: 2012-08-01
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __DSTRING_H
+#define __DSTRING_H
+
+#include "typedefs.h"
+
+typedef struct _DString DString;
+
+DString * dstring_new (int char_size, int n_elm);
+
+void dstring_free (DString *ds);
+
+int dstring_length (const DString *ds);
+
+const void * dstring_get_val (const DString *ds);
+
+void * dstring_get_val_rw (DString *ds);
+
+void dstring_clear (DString *ds);
+
+bool dstring_copy (DString *dst, const DString *src);
+
+bool dstring_append (DString *dst, const DString *src);
+
+bool dstring_append_string (DString *ds, const void *data, int len);
+
+bool dstring_append_char (DString *ds, const void *data);
+
+bool dstring_terminate (DString *ds);
+
+bool dstring_cut_last (DString *ds);
+
+#endif /* __DSTRING_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/tail.c b/src/datrie/tail.c
new file mode 100644
index 0000000..1464468
--- /dev/null
+++ b/src/datrie/tail.c
@@ -0,0 +1,388 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * tail.c - trie tail for keeping suffixes
+ * Created: 2006-08-15
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#ifndef _MSC_VER /* for SIZE_MAX */
+# include <stdint.h>
+#endif
+#include <stdio.h>
+
+#include "tail.h"
+
+/*----------------------------------*
+ * INTERNAL TYPES DECLARATIONS *
+ *----------------------------------*/
+
+/*-----------------------------------*
+ * PRIVATE METHODS DECLARATIONS *
+ *-----------------------------------*/
+
+static TrieIndex tail_alloc_block (Tail *t);
+static void tail_free_block (Tail *t, TrieIndex block);
+
+/* ==================== BEGIN IMPLEMENTATION PART ==================== */
+
+/*------------------------------------*
+ * INTERNAL TYPES IMPLEMENTATIONS *
+ *------------------------------------*/
+
+/*------------------------------*
+ * PRIVATE DATA DEFINITONS *
+ *------------------------------*/
+
+typedef struct {
+ TrieIndex next_free;
+ TrieData data;
+ TrieChar *suffix;
+} TailBlock;
+
+struct _Tail {
+ TrieIndex num_tails;
+ TailBlock *tails;
+ TrieIndex first_free;
+};
+
+/*-----------------------------*
+ * METHODS IMPLEMENTAIONS *
+ *-----------------------------*/
+
+#define TAIL_SIGNATURE 0xDFFCDFFC
+#define TAIL_START_BLOCKNO 1
+
+/* Tail Header:
+ * INT32: signature
+ * INT32: pointer to first free slot
+ * INT32: number of tail blocks
+ *
+ * Tail Blocks:
+ * INT32: pointer to next free block (-1 for allocated blocks)
+ * INT32: data for the key
+ * INT16: length
+ * BYTES[length]: suffix string (no terminating '\0')
+ */
+
+/**
+ * @brief Create a new tail object
+ *
+ * Create a new empty tail object.
+ */
+Tail *
+tail_new (void)
+{
+ Tail *t;
+
+ t = (Tail *) malloc (sizeof (Tail));
+ if (!t)
+ return NULL;
+
+ t->first_free = 0;
+ t->num_tails = 0;
+ t->tails = NULL;
+
+ return t;
+}
+
+/**
+ * @brief Free tail data
+ *
+ * @param t : the tail data
+ *
+ * @return 0 on success, non-zero on failure
+ *
+ * Free the given tail data.
+ */
+void
+tail_free (Tail *t)
+{
+ TrieIndex i;
+
+ if (t->tails) {
+ for (i = 0; i < t->num_tails; i++)
+ if (t->tails[i].suffix)
+ free (t->tails[i].suffix);
+ free (t->tails);
+ }
+ free (t);
+}
+
+
+/**
+ * @brief Get suffix
+ *
+ * @param t : the tail data
+ * @param index : the index of the suffix
+ *
+ * @return pointer to the indexed suffix string.
+ *
+ * Get suffix from tail with given @a index. The returned string is a pointer
+ * to internal storage, which should be accessed read-only by the caller.
+ * No need to free() it.
+ */
+const TrieChar *
+tail_get_suffix (const Tail *t, TrieIndex index)
+{
+ index -= TAIL_START_BLOCKNO;
+ return (index < t->num_tails) ? t->tails[index].suffix : NULL;
+}
+
+/**
+ * @brief Set suffix of existing entry
+ *
+ * @param t : the tail data
+ * @param index : the index of the suffix
+ * @param suffix : the new suffix
+ *
+ * Set suffix of existing entry of given @a index in tail.
+ */
+bool
+tail_set_suffix (Tail *t, TrieIndex index, const TrieChar *suffix)
+{
+ index -= TAIL_START_BLOCKNO;
+ if (index < t->num_tails) {
+ /* suffix and t->tails[index].suffix may overlap;
+ * so, dup it before it's overwritten
+ */
+ TrieChar *tmp = NULL;
+ if (suffix)
+ tmp = (TrieChar *) strdup ((const char *)suffix);
+ if (t->tails[index].suffix)
+ free (t->tails[index].suffix);
+ t->tails[index].suffix = tmp;
+
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Add a new suffix
+ *
+ * @param t : the tail data
+ * @param suffix : the new suffix
+ *
+ * @return the index of the newly added suffix.
+ *
+ * Add a new suffix entry to tail.
+ */
+TrieIndex
+tail_add_suffix (Tail *t, const TrieChar *suffix)
+{
+ TrieIndex new_block;
+
+ new_block = tail_alloc_block (t);
+ tail_set_suffix (t, new_block, suffix);
+
+ return new_block;
+}
+
+static TrieIndex
+tail_alloc_block (Tail *t)
+{
+ TrieIndex block;
+
+ if (0 != t->first_free) {
+ block = t->first_free;
+ t->first_free = t->tails[block].next_free;
+ } else {
+ block = t->num_tails;
+ t->tails = (TailBlock *) realloc (t->tails,
+ ++t->num_tails * sizeof (TailBlock));
+ }
+ t->tails[block].next_free = -1;
+ t->tails[block].data = TRIE_DATA_ERROR;
+ t->tails[block].suffix = NULL;
+
+ return block + TAIL_START_BLOCKNO;
+}
+
+static void
+tail_free_block (Tail *t, TrieIndex block)
+{
+ TrieIndex i, j;
+
+ block -= TAIL_START_BLOCKNO;
+
+ if (block >= t->num_tails)
+ return;
+
+ t->tails[block].data = TRIE_DATA_ERROR;
+ if (NULL != t->tails[block].suffix) {
+ free (t->tails[block].suffix);
+ t->tails[block].suffix = NULL;
+ }
+
+ /* find insertion point */
+ j = 0;
+ for (i = t->first_free; i != 0 && i < block; i = t->tails[i].next_free)
+ j = i;
+
+ /* insert free block between j and i */
+ t->tails[block].next_free = i;
+ if (0 != j)
+ t->tails[j].next_free = block;
+ else
+ t->first_free = block;
+}
+
+/**
+ * @brief Get data associated to suffix entry
+ *
+ * @param t : the tail data
+ * @param index : the index of the suffix
+ *
+ * @return the data associated to the suffix entry
+ *
+ * Get data associated to suffix entry @a index in tail data.
+ */
+TrieData
+tail_get_data (const Tail *t, TrieIndex index)
+{
+ index -= TAIL_START_BLOCKNO;
+ return (index < t->num_tails) ? t->tails[index].data : TRIE_DATA_ERROR;
+}
+
+/**
+ * @brief Set data associated to suffix entry
+ *
+ * @param t : the tail data
+ * @param index : the index of the suffix
+ * @param data : the data to set
+ *
+ * @return boolean indicating success
+ *
+ * Set data associated to suffix entry @a index in tail data.
+ */
+bool
+tail_set_data (Tail *t, TrieIndex index, TrieData data)
+{
+ index -= TAIL_START_BLOCKNO;
+ if (index < t->num_tails) {
+ t->tails[index].data = data;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Delete suffix entry
+ *
+ * @param t : the tail data
+ * @param index : the index of the suffix to delete
+ *
+ * Delete suffix entry from the tail data.
+ */
+void
+tail_delete (Tail *t, TrieIndex index)
+{
+ tail_free_block (t, index);
+}
+
+/**
+ * @brief Walk in tail with a string
+ *
+ * @param t : the tail data
+ * @param s : the tail data index
+ * @param suffix_idx : pointer to current character index in suffix
+ * @param str : the string to use in walking
+ * @param len : total characters in @a str to walk
+ *
+ * @return total number of characters successfully walked
+ *
+ * Walk in the tail data @a t at entry @a s, from given character position
+ * @a *suffix_idx, using @a len characters of given string @a str. On return,
+ * @a *suffix_idx is updated to the position after the last successful walk,
+ * and the function returns the total number of character succesfully walked.
+ */
+int
+tail_walk_str (const Tail *t,
+ TrieIndex s,
+ short *suffix_idx,
+ const TrieChar *str,
+ int len)
+{
+ const TrieChar *suffix;
+ int i;
+ short j;
+
+ suffix = tail_get_suffix (t, s);
+ if (!suffix)
+ return false;
+
+ i = 0; j = *suffix_idx;
+ while (i < len) {
+ if (str[i] != suffix[j])
+ break;
+ ++i;
+ /* stop and stay at null-terminator */
+ if (0 == suffix[j])
+ break;
+ ++j;
+ }
+ *suffix_idx = j;
+ return i;
+}
+
+/**
+ * @brief Walk in tail with a character
+ *
+ * @param t : the tail data
+ * @param s : the tail data index
+ * @param suffix_idx : pointer to current character index in suffix
+ * @param c : the character to use in walking
+ *
+ * @return boolean indicating success
+ *
+ * Walk in the tail data @a t at entry @a s, from given character position
+ * @a *suffix_idx, using given character @a c. If the walk is successful,
+ * it returns true, and @a *suffix_idx is updated to the next character.
+ * Otherwise, it returns false, and @a *suffix_idx is left unchanged.
+ */
+bool
+tail_walk_char (const Tail *t,
+ TrieIndex s,
+ short *suffix_idx,
+ TrieChar c)
+{
+ const TrieChar *suffix;
+ TrieChar suffix_char;
+
+ suffix = tail_get_suffix (t, s);
+ if (!suffix)
+ return false;
+
+ suffix_char = suffix[*suffix_idx];
+ if (suffix_char == c) {
+ if (0 != suffix_char)
+ ++*suffix_idx;
+ return true;
+ }
+ return false;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/tail.h b/src/datrie/tail.h
new file mode 100644
index 0000000..d2f6cd5
--- /dev/null
+++ b/src/datrie/tail.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * tail.h - trie tail for keeping suffixes
+ * Created: 2006-08-12
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TAIL_H
+#define __TAIL_H
+
+#include "triedefs.h"
+
+/**
+ * @file tail.h
+ * @brief trie tail for keeping suffixes
+ */
+
+/**
+ * @brief Double-array structure type
+ */
+typedef struct _Tail Tail;
+
+Tail * tail_new (void);
+
+void tail_free (Tail *t);
+
+
+const TrieChar * tail_get_suffix (const Tail *t, TrieIndex index);
+
+bool tail_set_suffix (Tail *t, TrieIndex index, const TrieChar *suffix);
+
+TrieIndex tail_add_suffix (Tail *t, const TrieChar *suffix);
+
+TrieData tail_get_data (const Tail *t, TrieIndex index);
+
+bool tail_set_data (Tail *t, TrieIndex index, TrieData data);
+
+void tail_delete (Tail *t, TrieIndex index);
+
+int tail_walk_str (const Tail *t,
+ TrieIndex s,
+ short *suffix_idx,
+ const TrieChar *str,
+ int len);
+
+bool tail_walk_char (const Tail *t,
+ TrieIndex s,
+ short *suffix_idx,
+ TrieChar c);
+
+/**
+ * @brief Test walkability in tail with a character
+ *
+ * @param t : the tail data
+ * @param s : the tail data index
+ * @param suffix_idx : current character index in suffix
+ * @param c : the character to test walkability
+ *
+ * @return boolean indicating walkability
+ *
+ * Test if the character @a c can be used to walk from given character
+ * position @a suffix_idx of entry @a s of the tail data @a t.
+ */
+/*
+bool tail_is_walkable_char (Tail *t,
+ TrieIndex s,
+ short suffix_idx,
+ const TrieChar c);
+*/
+#define tail_is_walkable_char(t,s,suffix_idx,c) \
+ (tail_get_suffix ((t), (s)) [suffix_idx] == (c))
+
+#endif /* __TAIL_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/trie-private.h b/src/datrie/trie-private.h
new file mode 100644
index 0000000..706d704
--- /dev/null
+++ b/src/datrie/trie-private.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * trie-private.h - Private utilities for trie implementation
+ * Created: 2007-08-25
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TRIE_PRIVATE_H
+#define __TRIE_PRIVATE_H
+
+#include <datrie/typedefs.h>
+
+/**
+ * @file trie-private.h
+ * @brief Private utilities for trie implementation
+ */
+
+/**
+ * @brief Minimum value macro
+ */
+#define MIN_VAL(a,b) ((a)<(b)?(a):(b))
+/**
+ * @brief Maximum value macro
+ */
+#define MAX_VAL(a,b) ((a)>(b)?(a):(b))
+
+#endif /* __TRIE_PRIVATE_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/trie-string.c b/src/datrie/trie-string.c
new file mode 100644
index 0000000..dd2d3fd
--- /dev/null
+++ b/src/datrie/trie-string.c
@@ -0,0 +1,114 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * trie-string.c - Dynamic string type for Trie alphabets
+ * Created: 2012-08-02
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include "trie-string.h"
+#include "dstring-private.h"
+#include "triedefs.h"
+
+#include <string.h>
+
+
+struct _TrieString {
+ DString ds;
+};
+
+
+TrieString *
+trie_string_new (int n_elm)
+{
+ return (TrieString *) dstring_new (sizeof (TrieChar), n_elm);
+}
+
+void
+trie_string_free (TrieString *ts)
+{
+ dstring_free ((DString *)ts);
+}
+
+int
+trie_string_length (const TrieString *ts)
+{
+ return dstring_length ((DString *)ts);
+}
+
+const void *
+trie_string_get_val (const TrieString *ts)
+{
+ return dstring_get_val ((DString *)ts);
+}
+
+void *
+trie_string_get_val_rw (TrieString *ts)
+{
+ return dstring_get_val_rw ((DString *)ts);
+}
+
+void
+trie_string_clear (TrieString *ts)
+{
+ dstring_clear ((DString *)ts);
+}
+
+bool
+trie_string_copy (TrieString *dst, const TrieString *src)
+{
+ return dstring_copy ((DString *)dst, (const DString *)src);
+}
+
+bool
+trie_string_append (TrieString *dst, const TrieString *src)
+{
+ return dstring_append ((DString *)dst, (const DString *)src);
+}
+
+bool
+trie_string_append_string (TrieString *ts, const TrieChar *str)
+{
+ return dstring_append_string ((DString *)ts,
+ str, strlen ((const char *)str));
+}
+
+bool
+trie_string_append_char (TrieString *ts, TrieChar tc)
+{
+ return dstring_append_char ((DString *)ts, &tc);
+}
+
+bool
+trie_string_terminate (TrieString *ts)
+{
+ return dstring_terminate ((DString *)ts);
+}
+
+bool
+trie_string_cut_last (TrieString *ts)
+{
+ return dstring_cut_last ((DString *)ts);
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/trie-string.h b/src/datrie/trie-string.h
new file mode 100644
index 0000000..851d37a
--- /dev/null
+++ b/src/datrie/trie-string.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * trie-string.h - Dynamic string type for Trie alphabets
+ * Created: 2012-08-02
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TRIE_STRING_H
+#define __TRIE_STRING_H
+
+#include "dstring.h"
+#include "triedefs.h"
+
+typedef struct _TrieString TrieString;
+
+TrieString * trie_string_new (int n_elm);
+
+void trie_string_free (TrieString *ts);
+
+int trie_string_length (const TrieString *ts);
+
+const void * trie_string_get_val (const TrieString *ts);
+
+void * trie_string_get_val_rw (TrieString *ts);
+
+void trie_string_clear (TrieString *ts);
+
+bool trie_string_copy (TrieString *dst, const TrieString *src);
+
+bool trie_string_append (TrieString *dst, const TrieString *src);
+
+bool trie_string_append_string (TrieString *ts, const TrieChar *str);
+
+bool trie_string_append_char (TrieString *ts, TrieChar tc);
+
+bool trie_string_terminate (TrieString *ts);
+
+bool trie_string_cut_last (TrieString *ts);
+
+
+#endif /* __TRIE_STRING_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
+
diff --git a/src/datrie/trie.c b/src/datrie/trie.c
new file mode 100644
index 0000000..2d0a2da
--- /dev/null
+++ b/src/datrie/trie.c
@@ -0,0 +1,958 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * trie.c - Trie data type and functions
+ * Created: 2006-08-11
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "trie.h"
+#include "alpha-map.h"
+#include "alpha-map-private.h"
+#include "darray.h"
+#include "tail.h"
+#include "trie-string.h"
+
+/**
+ * @brief Trie structure
+ */
+struct _Trie {
+ AlphaMap *alpha_map;
+ DArray *da;
+ Tail *tail;
+
+ bool is_dirty;
+};
+
+/**
+ * @brief TrieState structure
+ */
+struct _TrieState {
+ const Trie *trie; /**< the corresponding trie */
+ TrieIndex index; /**< index in double-array/tail structures */
+ short suffix_idx; /**< suffix character offset, if in suffix */
+ short is_suffix; /**< whether it is currently in suffix part */
+};
+
+/**
+ * @brief TrieIterator structure
+ */
+struct _TrieIterator {
+ const TrieState *root; /**< the state to start iteration from */
+ TrieState *state; /**< the current state */
+ TrieString *key; /**< buffer for calculating the entry key */
+};
+
+
+/*------------------------*
+ * INTERNAL FUNCTIONS *
+ *------------------------*/
+
+#define trie_da_is_separate(da,s) (da_get_base ((da), (s)) < 0)
+#define trie_da_get_tail_index(da,s) (-da_get_base ((da), (s)))
+#define trie_da_set_tail_index(da,s,v) (da_set_base ((da), (s), -(v)))
+
+static TrieState * trie_state_new (const Trie *trie,
+ TrieIndex index,
+ short suffix_idx,
+ short is_suffix);
+
+static bool trie_store_conditionally (Trie *trie,
+ const AlphaChar *key,
+ TrieData data,
+ bool is_overwrite);
+
+static bool trie_branch_in_branch (Trie *trie,
+ TrieIndex sep_node,
+ const TrieChar *suffix,
+ TrieData data);
+
+static bool trie_branch_in_tail (Trie *trie,
+ TrieIndex sep_node,
+ const TrieChar *suffix,
+ TrieData data);
+
+/*-----------------------*
+ * GENERAL FUNCTIONS *
+ *-----------------------*/
+
+/**
+ * @brief Create a new trie
+ *
+ * @param alpha_map : the alphabet set for the trie
+ *
+ * @return a pointer to the newly created trie, NULL on failure
+ *
+ * Create a new empty trie object based on the given @a alpha_map alphabet
+ * set. The trie contents can then be added and deleted with trie_store() and
+ * trie_delete() respectively.
+ *
+ * The created object must be freed with trie_free().
+ */
+Trie *
+trie_new (const AlphaMap *alpha_map)
+{
+ Trie *trie;
+
+ trie = (Trie *) malloc (sizeof (Trie));
+ if (!trie)
+ return NULL;
+
+ trie->alpha_map = alpha_map_clone (alpha_map);
+ if (!trie->alpha_map)
+ goto exit_trie_created;
+
+ trie->da = da_new ();
+ if (!trie->da)
+ goto exit_alpha_map_created;
+
+ trie->tail = tail_new ();
+ if (!trie->tail)
+ goto exit_da_created;
+
+ trie->is_dirty = true;
+ return trie;
+
+exit_da_created:
+ da_free (trie->da);
+exit_alpha_map_created:
+ alpha_map_free (trie->alpha_map);
+exit_trie_created:
+ free (trie);
+ return NULL;
+}
+
+/**
+ * @brief Free a trie object
+ *
+ * @param trie : the trie object to free
+ *
+ * Destruct the @a trie and free its allocated memory.
+ */
+void
+trie_free (Trie *trie)
+{
+ alpha_map_free (trie->alpha_map);
+ da_free (trie->da);
+ tail_free (trie->tail);
+ free (trie);
+}
+
+/**
+ * @brief Check pending changes
+ *
+ * @param trie : the trie object
+ *
+ * @return true if there are pending changes, false otherwise
+ *
+ * Check if the @a trie is dirty with some pending changes and needs saving
+ * to synchronize with the file.
+ */
+bool
+trie_is_dirty (const Trie *trie)
+{
+ return trie->is_dirty;
+}
+
+
+/*------------------------------*
+ * GENERAL QUERY OPERATIONS *
+ *------------------------------*/
+
+/**
+ * @brief Retrieve an entry from trie
+ *
+ * @param trie : the trie
+ * @param key : the key for the entry to retrieve
+ * @param o_data : the storage for storing the entry data on return
+ *
+ * @return boolean value indicating the existence of the entry.
+ *
+ * Retrieve an entry for the given @a key from @a trie. On return,
+ * if @a key is found and @a o_data is not NULL, @a *o_data is set
+ * to the data associated to @a key.
+ */
+bool
+trie_retrieve (const Trie *trie, const AlphaChar *key, TrieData *o_data)
+{
+ TrieIndex s;
+ short suffix_idx;
+ const AlphaChar *p;
+
+ /* walk through branches */
+ s = da_get_root (trie->da);
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!da_walk (trie->da, &s, (TrieChar) tc))
+ return false;
+ if (0 == *p)
+ break;
+ }
+
+ /* walk through tail */
+ s = trie_da_get_tail_index (trie->da, s);
+ suffix_idx = 0;
+ for ( ; ; p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!tail_walk_char (trie->tail, s, &suffix_idx, (TrieChar) tc))
+ return false;
+ if (0 == *p)
+ break;
+ }
+
+ /* found, set the val and return */
+ if (o_data)
+ *o_data = tail_get_data (trie->tail, s);
+ return true;
+}
+
+/**
+ * @brief Store a value for an entry to trie
+ *
+ * @param trie : the trie
+ * @param key : the key for the entry to retrieve
+ * @param data : the data associated to the entry
+ *
+ * @return boolean value indicating the success of the operation
+ *
+ * Store a @a data for the given @a key in @a trie. If @a key does not
+ * exist in @a trie, it will be appended. If it does, its current data will
+ * be overwritten.
+ */
+bool
+trie_store (Trie *trie, const AlphaChar *key, TrieData data)
+{
+ return trie_store_conditionally (trie, key, data, true);
+}
+
+/**
+ * @brief Store a value for an entry to trie only if the key is not present
+ *
+ * @param trie : the trie
+ * @param key : the key for the entry to retrieve
+ * @param data : the data associated to the entry
+ *
+ * @return boolean value indicating the success of the operation
+ *
+ * Store a @a data for the given @a key in @a trie. If @a key does not
+ * exist in @a trie, it will be appended. If it does, the function will
+ * return failure and the existing value will not be touched.
+ *
+ * This can be useful for multi-thread applications, as race condition
+ * can be avoided.
+ *
+ * Available since: 0.2.4
+ */
+bool
+trie_store_if_absent (Trie *trie, const AlphaChar *key, TrieData data)
+{
+ return trie_store_conditionally (trie, key, data, false);
+}
+
+static bool
+trie_store_conditionally (Trie *trie,
+ const AlphaChar *key,
+ TrieData data,
+ bool is_overwrite)
+{
+ TrieIndex s, t;
+ short suffix_idx;
+ const AlphaChar *p, *sep;
+
+ /* walk through branches */
+ s = da_get_root (trie->da);
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!da_walk (trie->da, &s, (TrieChar) tc)) {
+ TrieChar *key_str;
+ bool res;
+
+ key_str = alpha_map_char_to_trie_str (trie->alpha_map, p);
+ if (!key_str)
+ return false;
+ res = trie_branch_in_branch (trie, s, key_str, data);
+ free (key_str);
+
+ return res;
+ }
+ if (0 == *p)
+ break;
+ }
+
+ /* walk through tail */
+ sep = p;
+ t = trie_da_get_tail_index (trie->da, s);
+ suffix_idx = 0;
+ for ( ; ; p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!tail_walk_char (trie->tail, t, &suffix_idx, (TrieChar) tc)) {
+ TrieChar *tail_str;
+ bool res;
+
+ tail_str = alpha_map_char_to_trie_str (trie->alpha_map, sep);
+ if (!tail_str)
+ return false;
+ res = trie_branch_in_tail (trie, s, tail_str, data);
+ free (tail_str);
+
+ return res;
+ }
+ if (0 == *p)
+ break;
+ }
+
+ /* duplicated key, overwrite val if flagged */
+ if (!is_overwrite) {
+ return false;
+ }
+ tail_set_data (trie->tail, t, data);
+ trie->is_dirty = true;
+ return true;
+}
+
+static bool
+trie_branch_in_branch (Trie *trie,
+ TrieIndex sep_node,
+ const TrieChar *suffix,
+ TrieData data)
+{
+ TrieIndex new_da, new_tail;
+
+ new_da = da_insert_branch (trie->da, sep_node, *suffix);
+ if (TRIE_INDEX_ERROR == new_da)
+ return false;
+
+ if ('\0' != *suffix)
+ ++suffix;
+
+ new_tail = tail_add_suffix (trie->tail, suffix);
+ tail_set_data (trie->tail, new_tail, data);
+ trie_da_set_tail_index (trie->da, new_da, new_tail);
+
+ trie->is_dirty = true;
+ return true;
+}
+
+static bool
+trie_branch_in_tail (Trie *trie,
+ TrieIndex sep_node,
+ const TrieChar *suffix,
+ TrieData data)
+{
+ TrieIndex old_tail, old_da, s;
+ const TrieChar *old_suffix, *p;
+
+ /* adjust separate point in old path */
+ old_tail = trie_da_get_tail_index (trie->da, sep_node);
+ old_suffix = tail_get_suffix (trie->tail, old_tail);
+ if (!old_suffix)
+ return false;
+
+ for (p = old_suffix, s = sep_node; *p == *suffix; p++, suffix++) {
+ TrieIndex t = da_insert_branch (trie->da, s, *p);
+ if (TRIE_INDEX_ERROR == t)
+ goto fail;
+ s = t;
+ }
+
+ old_da = da_insert_branch (trie->da, s, *p);
+ if (TRIE_INDEX_ERROR == old_da)
+ goto fail;
+
+ if ('\0' != *p)
+ ++p;
+ tail_set_suffix (trie->tail, old_tail, p);
+ trie_da_set_tail_index (trie->da, old_da, old_tail);
+
+ /* insert the new branch at the new separate point */
+ return trie_branch_in_branch (trie, s, suffix, data);
+
+fail:
+ /* failed, undo previous insertions and return error */
+ da_prune_upto (trie->da, sep_node, s);
+ trie_da_set_tail_index (trie->da, sep_node, old_tail);
+ return false;
+}
+
+/**
+ * @brief Delete an entry from trie
+ *
+ * @param trie : the trie
+ * @param key : the key for the entry to delete
+ *
+ * @return boolean value indicating whether the key exists and is removed
+ *
+ * Delete an entry for the given @a key from @a trie.
+ */
+bool
+trie_delete (Trie *trie, const AlphaChar *key)
+{
+ TrieIndex s, t;
+ short suffix_idx;
+ const AlphaChar *p;
+
+ /* walk through branches */
+ s = da_get_root (trie->da);
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!da_walk (trie->da, &s, (TrieChar) tc))
+ return false;
+ if (0 == *p)
+ break;
+ }
+
+ /* walk through tail */
+ t = trie_da_get_tail_index (trie->da, s);
+ suffix_idx = 0;
+ for ( ; ; p++) {
+ TrieIndex tc = alpha_map_char_to_trie (trie->alpha_map, *p);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+ if (!tail_walk_char (trie->tail, t, &suffix_idx, (TrieChar) tc))
+ return false;
+ if (0 == *p)
+ break;
+ }
+
+ tail_delete (trie->tail, t);
+ da_set_base (trie->da, s, TRIE_INDEX_ERROR);
+ da_prune (trie->da, s);
+
+ trie->is_dirty = true;
+ return true;
+}
+
+/**
+ * @brief Enumerate entries in trie
+ *
+ * @param trie : the trie
+ * @param enum_func : the callback function to be called on each key
+ * @param user_data : user-supplied data to send as an argument to @a enum_func
+ *
+ * @return boolean value indicating whether all the keys are visited
+ *
+ * Enumerate all entries in trie. For each entry, the user-supplied
+ * @a enum_func callback function is called, with the entry key and data.
+ * Returning false from such callback will stop enumeration and return false.
+ */
+bool
+trie_enumerate (const Trie *trie, TrieEnumFunc enum_func, void *user_data)
+{
+ TrieState *root;
+ TrieIterator *iter;
+ bool cont = true;
+
+ root = trie_root (trie);
+ if (!root)
+ return false;
+
+ iter = trie_iterator_new (root);
+ if (!iter)
+ goto exit_root_created;
+
+ while (cont && trie_iterator_next (iter)) {
+ AlphaChar *key = trie_iterator_get_key (iter);
+ TrieData data = trie_iterator_get_data (iter);
+ cont = (*enum_func) (key, data, user_data);
+ free (key);
+ }
+
+ trie_iterator_free (iter);
+ trie_state_free (root);
+
+ return cont;
+
+exit_root_created:
+ trie_state_free (root);
+ return false;
+}
+
+
+/*-------------------------------*
+ * STEPWISE QUERY OPERATIONS *
+ *-------------------------------*/
+
+/**
+ * @brief Get root state of a trie
+ *
+ * @param trie : the trie
+ *
+ * @return the root state of the trie
+ *
+ * Get root state of @a trie, for stepwise walking.
+ *
+ * The returned state is allocated and must be freed with trie_state_free()
+ */
+TrieState *
+trie_root (const Trie *trie)
+{
+ return trie_state_new (trie, da_get_root (trie->da), 0, false);
+}
+
+/*----------------*
+ * TRIE STATE *
+ *----------------*/
+
+static TrieState *
+trie_state_new (const Trie *trie,
+ TrieIndex index,
+ short suffix_idx,
+ short is_suffix)
+{
+ TrieState *s;
+
+ s = (TrieState *) malloc (sizeof (TrieState));
+ if (!s)
+ return NULL;
+
+ s->trie = trie;
+ s->index = index;
+ s->suffix_idx = suffix_idx;
+ s->is_suffix = is_suffix;
+
+ return s;
+}
+
+/**
+ * @brief Copy trie state to another
+ *
+ * @param dst : the destination state
+ * @param src : the source state
+ *
+ * Copy trie state data from @a src to @a dst. All existing data in @a dst
+ * is overwritten.
+ */
+void
+trie_state_copy (TrieState *dst, const TrieState *src)
+{
+ /* May be deep copy if necessary, not the case for now */
+ *dst = *src;
+}
+
+/**
+ * @brief Clone a trie state
+ *
+ * @param s : the state to clone
+ *
+ * @return an duplicated instance of @a s
+ *
+ * Make a copy of trie state.
+ *
+ * The returned state is allocated and must be freed with trie_state_free()
+ */
+TrieState *
+trie_state_clone (const TrieState *s)
+{
+ return trie_state_new (s->trie, s->index, s->suffix_idx, s->is_suffix);
+}
+
+/**
+ * @brief Free a trie state
+ *
+ * @param s : the state to free
+ *
+ * Free the trie state.
+ */
+void
+trie_state_free (TrieState *s)
+{
+ free (s);
+}
+
+/**
+ * @brief Rewind a trie state
+ *
+ * @param s : the state to rewind
+ *
+ * Put the state at root.
+ */
+void
+trie_state_rewind (TrieState *s)
+{
+ s->index = da_get_root (s->trie->da);
+ s->is_suffix = false;
+}
+
+/**
+ * @brief Walk the trie from the state
+ *
+ * @param s : current state
+ * @param c : key character for walking
+ *
+ * @return boolean value indicating the success of the walk
+ *
+ * Walk the trie stepwise, using a given character @a c.
+ * On return, the state @a s is updated to the new state if successfully walked.
+ */
+bool
+trie_state_walk (TrieState *s, AlphaChar c)
+{
+ TrieIndex tc = alpha_map_char_to_trie (s->trie->alpha_map, c);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+
+ if (!s->is_suffix) {
+ bool ret;
+
+ ret = da_walk (s->trie->da, &s->index, (TrieChar) tc);
+
+ if (ret && trie_da_is_separate (s->trie->da, s->index)) {
+ s->index = trie_da_get_tail_index (s->trie->da, s->index);
+ s->suffix_idx = 0;
+ s->is_suffix = true;
+ }
+
+ return ret;
+ } else {
+ return tail_walk_char (s->trie->tail, s->index, &s->suffix_idx,
+ (TrieChar) tc);
+ }
+}
+
+/**
+ * @brief Test walkability of character from state
+ *
+ * @param s : the state to check
+ * @param c : the input character
+ *
+ * @return boolean indicating walkability
+ *
+ * Test if there is a transition from state @a s with input character @a c.
+ */
+bool
+trie_state_is_walkable (const TrieState *s, AlphaChar c)
+{
+ TrieIndex tc = alpha_map_char_to_trie (s->trie->alpha_map, c);
+ if (TRIE_INDEX_MAX == tc)
+ return false;
+
+ if (!s->is_suffix)
+ return da_is_walkable (s->trie->da, s->index, (TrieChar) tc);
+ else
+ return tail_is_walkable_char (s->trie->tail, s->index, s->suffix_idx,
+ (TrieChar) tc);
+}
+
+/**
+ * @brief Get all walkable characters from state
+ *
+ * @param s : the state to get
+ * @param chars : the storage for the result
+ * @param chars_nelm : the size of @a chars[] in number of elements
+ *
+ * @return total walkable characters
+ *
+ * Get the list of all walkable characters from state @a s. At most
+ * @a chars_nelm walkable characters are stored in @a chars[] on return.
+ *
+ * The function returns the actual number of walkable characters from @a s.
+ * Note that this may not equal the number of characters stored in @a chars[]
+ * if @a chars_nelm is less than the actual number.
+ *
+ * Available since: 0.2.6
+ */
+int
+trie_state_walkable_chars (const TrieState *s,
+ AlphaChar chars[],
+ int chars_nelm)
+{
+ int syms_num = 0;
+
+ if (!s->is_suffix) {
+ Symbols *syms = da_output_symbols (s->trie->da, s->index);
+ int i;
+
+ syms_num = symbols_num (syms);
+ for (i = 0; i < syms_num && i < chars_nelm; i++) {
+ TrieChar tc = symbols_get (syms, i);
+ chars[i] = alpha_map_trie_to_char (s->trie->alpha_map, tc);
+ }
+
+ symbols_free (syms);
+ } else {
+ const TrieChar *suffix = tail_get_suffix (s->trie->tail, s->index);
+ chars[0] = alpha_map_trie_to_char (s->trie->alpha_map,
+ suffix[s->suffix_idx]);
+ syms_num = 1;
+ }
+
+ return syms_num;
+}
+
+/**
+ * @brief Check for single path
+ *
+ * @param s : the state to check
+ *
+ * @return boolean value indicating whether it is in a single path
+ *
+ * Check if the given state is in a single path, that is, there is no other
+ * branch from it to leaf.
+ */
+bool
+trie_state_is_single (const TrieState *s)
+{
+ return s->is_suffix;
+}
+
+/**
+ * @brief Get data from leaf state
+ *
+ * @param s : a leaf state
+ *
+ * @return the data associated with the leaf state @a s,
+ * or TRIE_DATA_ERROR if @a s is not a leaf state
+ *
+ * Get value from a leaf state of trie. Getting value from a non-leaf state
+ * will result in TRIE_DATA_ERROR.
+ */
+TrieData
+trie_state_get_data (const TrieState *s)
+{
+ return trie_state_is_leaf (s) ? tail_get_data (s->trie->tail, s->index)
+ : TRIE_DATA_ERROR;
+}
+
+
+/*---------------------*
+ * ENTRY ITERATION *
+ *---------------------*/
+
+/**
+ * @brief Create a new trie iterator
+ *
+ * @param s : the TrieState to start iteration from
+ *
+ * @return a pointer to the newly created TrieIterator, or NULL on failure
+ *
+ * Create a new trie iterator for iterating entries of a sub-trie rooted at
+ * state @a s.
+ *
+ * Use it with the result of trie_root() to iterate the whole trie.
+ *
+ * The created object must be freed with trie_iterator_free().
+ *
+ * Available since: 0.2.6
+ */
+TrieIterator *
+trie_iterator_new (TrieState *s)
+{
+ TrieIterator *iter;
+
+ iter = (TrieIterator *) malloc (sizeof (TrieIterator));
+ if (!iter)
+ return NULL;
+
+ iter->root = s;
+ iter->state = NULL;
+ iter->key = NULL;
+
+ return iter;
+}
+
+/**
+ * @brief Free a trie iterator
+ *
+ * @param iter : the trie iterator to free
+ *
+ * Destruct the iterator @a iter and free its allocated memory.
+ *
+ * Available since: 0.2.6
+ */
+void
+trie_iterator_free (TrieIterator *iter)
+{
+ if (iter->state) {
+ trie_state_free (iter->state);
+ }
+ if (iter->key) {
+ trie_string_free (iter->key);
+ }
+ free (iter);
+}
+
+/**
+ * @brief Move trie iterator to the next entry
+ *
+ * @param iter : an iterator
+ *
+ * @return boolean value indicating the availability of the entry
+ *
+ * Move trie iterator to the next entry.
+ * On return, the iterator @a iter is updated to reference to the new entry
+ * if successfully moved.
+ *
+ * Available since: 0.2.6
+ */
+bool
+trie_iterator_next (TrieIterator *iter)
+{
+ TrieState *s = iter->state;
+ TrieIndex sep;
+
+ /* first iteration */
+ if (!s) {
+ s = iter->state = trie_state_clone (iter->root);
+
+ /* for tail state, we are already at the only entry */
+ if (s->is_suffix)
+ return true;
+
+ iter->key = trie_string_new (20);
+ sep = da_first_separate (s->trie->da, s->index, iter->key);
+ if (TRIE_INDEX_ERROR == sep)
+ return false;
+
+ s->index = sep;
+ return true;
+ }
+
+ /* no next entry for tail state */
+ if (s->is_suffix)
+ return false;
+
+ /* iter->state is a separate node */
+ sep = da_next_separate (s->trie->da, iter->root->index, s->index,
+ iter->key);
+ if (TRIE_INDEX_ERROR == sep)
+ return false;
+
+ s->index = sep;
+ return true;
+}
+
+/**
+ * @brief Get key for a trie iterator
+ *
+ * @param iter : an iterator
+ *
+ * @return the allocated key string; NULL on failure
+ *
+ * Get key for the current entry referenced by the trie iterator @a iter.
+ *
+ * The return string must be freed with free().
+ *
+ * Available since: 0.2.6
+ */
+AlphaChar *
+trie_iterator_get_key (const TrieIterator *iter)
+{
+ const TrieState *s;
+ const TrieChar *tail_str;
+ AlphaChar *alpha_key, *alpha_p;
+
+ s = iter->state;
+ if (!s)
+ return NULL;
+
+ /* if s is in tail, root == s */
+ if (s->is_suffix) {
+ tail_str = tail_get_suffix (s->trie->tail, s->index);
+ if (!tail_str)
+ return NULL;
+
+ tail_str += s->suffix_idx;
+
+ alpha_key = (AlphaChar *) malloc (sizeof (AlphaChar)
+ * (strlen ((const char *)tail_str)
+ + 1));
+ alpha_p = alpha_key;
+ } else {
+ TrieIndex tail_idx;
+ int i, key_len;
+ const TrieChar *key_p;
+
+ tail_idx = trie_da_get_tail_index (s->trie->da, s->index);
+ tail_str = tail_get_suffix (s->trie->tail, tail_idx);
+ if (!tail_str)
+ return NULL;
+
+ key_len = trie_string_length (iter->key);
+ key_p = trie_string_get_val (iter->key);
+ alpha_key = (AlphaChar *) malloc (
+ sizeof (AlphaChar)
+ * (key_len + strlen ((const char *)tail_str) + 1)
+ );
+ alpha_p = alpha_key;
+ for (i = key_len; i > 0; i--) {
+ *alpha_p++ = alpha_map_trie_to_char (s->trie->alpha_map, *key_p++);
+ }
+ }
+
+ while (*tail_str) {
+ *alpha_p++ = alpha_map_trie_to_char (s->trie->alpha_map, *tail_str++);
+ }
+ *alpha_p = 0;
+
+ return alpha_key;
+}
+
+/**
+ * @brief Get data for the entry referenced by an iterator
+ *
+ * @param iter : an iterator
+ *
+ * @return the data associated with the entry referenced by iterator @a iter,
+ * or TRIE_DATA_ERROR if @a iter does not reference to a unique entry
+ *
+ * Get value for the entry referenced by an iterator. Getting value from an
+ * un-iterated (or broken for any reason) iterator will result in
+ * TRIE_DATA_ERROR.
+ *
+ * Available since: 0.2.6
+ */
+TrieData
+trie_iterator_get_data (const TrieIterator *iter)
+{
+ const TrieState *s = iter->state;
+ TrieIndex tail_index;
+
+ if (!s)
+ return TRIE_DATA_ERROR;
+
+ if (!s->is_suffix) {
+ if (!trie_da_is_separate (s->trie->da, s->index))
+ return TRIE_DATA_ERROR;
+
+ tail_index = trie_da_get_tail_index (s->trie->da, s->index);
+ } else {
+ tail_index = s->index;
+ }
+
+ return tail_get_data (s->trie->tail, tail_index);
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/trie.h b/src/datrie/trie.h
new file mode 100644
index 0000000..6bce522
--- /dev/null
+++ b/src/datrie/trie.h
@@ -0,0 +1,220 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * trie.h - Trie data type and functions
+ * Created: 2006-08-11
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TRIE_H
+#define __TRIE_H
+
+#include <datrie/triedefs.h>
+#include <datrie/alpha-map.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file trie.h
+ * @brief Trie data type and functions
+ *
+ * Trie is a kind of digital search tree, an efficient indexing method with
+ * O(1) time complexity for searching. Comparably as efficient as hashing,
+ * trie also provides flexibility on incremental matching and key spelling
+ * manipulation. This makes it ideal for lexical analyzers, as well as
+ * spelling dictionaries.
+ *
+ * This library is an implementation of double-array structure for representing
+ * trie, as proposed by Junichi Aoe. The details of the implementation can be
+ * found at http://linux.thai.net/~thep/datrie/datrie.html
+ *
+ * A Trie is associated with an AlphaMap, a map between actual alphabet
+ * characters and the raw character used to walk through trie.
+ * You can define the alphabet set by adding ranges of character codes
+ * to it before associating it to a trie. And the keys to be added to the trie
+ * must be only in such ranges.
+ *
+ * A new Trie can be created in memory using trie_new()
+ * It can even be embeded in another file using trie_fwrite() and read back
+ * using trie_fread().
+ * After use, Trie objects must be freed using trie_free().
+ *
+ * Operations on trie include:
+ *
+ * - Add/delete entries with trie_store() and trie_delete()
+ * - Retrieve entries with trie_retrieve()
+ * - Walk through trie stepwise with TrieState and its functions
+ * (trie_root(), trie_state_walk(), trie_state_rewind(),
+ * trie_state_clone(), trie_state_copy(),
+ * trie_state_is_walkable(), trie_state_walkable_chars(),
+ * trie_state_is_single(), trie_state_get_data().
+ * And do not forget to free TrieState objects with trie_state_free()
+ * after use.)
+ * - Enumerate all keys using trie_enumerate()
+ * - Iterate entries using TrieIterator and its functions
+ * (trie_iterator_new(), trie_iterator_next(), trie_iterator_get_key(),
+ * trie_iterator_get_data().
+ * And do not forget to free TrieIterator objects with trie_iterator_free()
+ * after use.)
+ */
+
+/**
+ * @brief Trie data type
+ */
+typedef struct _Trie Trie;
+
+/**
+ * @brief Trie enumeration function
+ *
+ * @param key : the key of the entry
+ * @param data : the data of the entry
+ * @param user_data : the user-supplied data on enumerate call
+ *
+ * @return true to continue enumeration, false to stop
+ */
+typedef bool (*TrieEnumFunc) (const AlphaChar *key,
+ TrieData key_data,
+ void *user_data);
+
+/**
+ * @brief Trie walking state
+ */
+typedef struct _TrieState TrieState;
+
+
+/**
+ * @brief Trie iteration state
+ */
+typedef struct _TrieIterator TrieIterator;
+
+/*-----------------------*
+ * GENERAL FUNCTIONS *
+ *-----------------------*/
+
+Trie * trie_new (const AlphaMap *alpha_map);
+
+void trie_free (Trie *trie);
+
+bool trie_is_dirty (const Trie *trie);
+
+
+/*------------------------------*
+ * GENERAL QUERY OPERATIONS *
+ *------------------------------*/
+
+bool trie_retrieve (const Trie *trie,
+ const AlphaChar *key,
+ TrieData *o_data);
+
+bool trie_store (Trie *trie, const AlphaChar *key, TrieData data);
+
+bool trie_store_if_absent (Trie *trie, const AlphaChar *key, TrieData data);
+
+bool trie_delete (Trie *trie, const AlphaChar *key);
+
+bool trie_enumerate (const Trie *trie,
+ TrieEnumFunc enum_func,
+ void *user_data);
+
+
+/*-------------------------------*
+ * STEPWISE QUERY OPERATIONS *
+ *-------------------------------*/
+
+TrieState * trie_root (const Trie *trie);
+
+
+/*----------------*
+ * TRIE STATE *
+ *----------------*/
+
+TrieState * trie_state_clone (const TrieState *s);
+
+void trie_state_copy (TrieState *dst, const TrieState *src);
+
+void trie_state_free (TrieState *s);
+
+void trie_state_rewind (TrieState *s);
+
+bool trie_state_walk (TrieState *s, AlphaChar c);
+
+bool trie_state_is_walkable (const TrieState *s, AlphaChar c);
+
+int trie_state_walkable_chars (const TrieState *s,
+ AlphaChar chars[],
+ int chars_nelm);
+
+/**
+ * @brief Check for terminal state
+ *
+ * @param s : the state to check
+ *
+ * @return boolean value indicating whether it is a terminal state
+ *
+ * Check if the given state is a terminal state. A terminal state is a trie
+ * state that terminates a key, and stores a value associated with it.
+ */
+#define trie_state_is_terminal(s) trie_state_is_walkable((s),TRIE_CHAR_TERM)
+
+bool trie_state_is_single (const TrieState *s);
+
+/**
+ * @brief Check for leaf state
+ *
+ * @param s : the state to check
+ *
+ * @return boolean value indicating whether it is a leaf state
+ *
+ * Check if the given state is a leaf state. A leaf state is a terminal state
+ * that has no other branch.
+ */
+#define trie_state_is_leaf(s) \
+ (trie_state_is_single(s) && trie_state_is_terminal(s))
+
+TrieData trie_state_get_data (const TrieState *s);
+
+
+/*----------------------*
+ * ENTRY ITERATION *
+ *----------------------*/
+
+TrieIterator * trie_iterator_new (TrieState *s);
+
+void trie_iterator_free (TrieIterator *iter);
+
+bool trie_iterator_next (TrieIterator *iter);
+
+AlphaChar * trie_iterator_get_key (const TrieIterator *iter);
+
+TrieData trie_iterator_get_data (const TrieIterator *iter);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TRIE_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/triedefs.h b/src/datrie/triedefs.h
new file mode 100644
index 0000000..c0060b9
--- /dev/null
+++ b/src/datrie/triedefs.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * triedefs.h - General typedefs for trie
+ * Created: 2006-08-11
+ * Author: Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TRIEDEFS_H
+#define __TRIEDEFS_H
+
+#include <stdint.h>
+#include <datrie/typedefs.h>
+
+/**
+ * @file triedefs.h
+ * @brief General typedefs for trie
+ */
+
+/**
+ * @brief Alphabet character type for use as input/output strings of trie keys
+ */
+typedef char AlphaChar;
+
+/**
+ * @brief Error value for alphabet character
+ */
+#define ALPHA_CHAR_ERROR (~(AlphaChar)0)
+
+/**
+ * @brief Raw character type mapped into packed set from AlphaChar,
+ * for use in actual trie transition calculations
+ */
+typedef uint8_t TrieChar;
+/**
+ * @brief Trie terminator character
+ */
+#define TRIE_CHAR_TERM ((TrieChar) 0)
+#define TRIE_CHAR_MAX UINT8_MAX
+
+/**
+ * @brief Type of index into Trie double-array and tail structures
+ */
+typedef int32_t TrieIndex;
+/**
+ * @brief Trie error index
+ */
+#define TRIE_INDEX_ERROR ((TrieIndex) 0)
+/**
+ * @brief Maximum trie index value
+ */
+#define TRIE_INDEX_MAX INT32_MAX
+
+/**
+ * @brief Type of value associated to trie entries
+ */
+typedef intptr_t TrieData;
+/**
+ * @brief Trie error data
+ */
+#define TRIE_DATA_ERROR ((TrieData) -1)
+
+#endif /* __TRIEDEFS_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/datrie/typedefs.h b/src/datrie/typedefs.h
new file mode 100644
index 0000000..0e89c70
--- /dev/null
+++ b/src/datrie/typedefs.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2006 Theppitak Karoonboonyanan <thep at linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * typedefs.h - general types
+ * Created : 11 Aug 2006
+ * Author : Theppitak Karoonboonyanan <thep at linux.thai.net>
+ */
+
+#ifndef __TYPEDEFS_H
+#define __TYPEDEFS_H
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef uint8_t byte;
+typedef uint16_t word;
+typedef uint32_t dword;
+
+
+#endif /* __TYPEDEFS_H */
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/src/gsl/combination.c b/src/gsl/combination.c
new file mode 100644
index 0000000..6401c04
--- /dev/null
+++ b/src/gsl/combination.c
@@ -0,0 +1,171 @@
+/* combination/combination.c
+ * based on permutation/permutation.c by Brian Gough
+ *
+ * Copyright (C) 2001 Szymon Jaroszewicz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "gsl_errno.h"
+#include "gsl_combination.h"
+
+size_t
+gsl_combination_n (const gsl_combination * c)
+{
+ return c->n ;
+}
+
+size_t
+gsl_combination_k (const gsl_combination * c)
+{
+ return c->k ;
+}
+
+size_t *
+gsl_combination_data (const gsl_combination * c)
+{
+ return c->data ;
+}
+
+int
+gsl_combination_valid (gsl_combination * c)
+{
+ const size_t n = c->n ;
+ const size_t k = c->k ;
+
+ size_t i, j ;
+
+ if( k > n )
+ {
+ GSL_ERROR("combination has k greater than n", GSL_FAILURE) ;
+ }
+ for (i = 0; i < k; i++)
+ {
+ const size_t ci = c->data[i];
+
+ if (ci >= n)
+ {
+ GSL_ERROR("combination index outside range", GSL_FAILURE) ;
+ }
+
+ for (j = 0; j < i; j++)
+ {
+ if (c->data[j] == ci)
+ {
+ GSL_ERROR("duplicate combination index", GSL_FAILURE) ;
+ }
+ if (c->data[j] > ci)
+ {
+ GSL_ERROR("combination indices not in increasing order",
+ GSL_FAILURE) ;
+ }
+ }
+ }
+
+ return GSL_SUCCESS;
+}
+
+
+int
+gsl_combination_next (gsl_combination * c)
+{
+ /* Replaces c with the next combination (in the standard lexicographical
+ * ordering). Returns GSL_FAILURE if there is no next combination.
+ */
+ const size_t n = c->n;
+ const size_t k = c->k;
+ size_t *data = c->data;
+ size_t i;
+
+ if(k == 0)
+ {
+ return GSL_FAILURE;
+ }
+ i = k - 1;
+
+ while(i > 0 && data[i] == n - k + i)
+ {
+ i--;
+ }
+ if(i == 0 && data[i] == n - k)
+ {
+ return GSL_FAILURE;
+ }
+ data[i]++;
+ for(; i < k - 1; i++)
+ {
+ data[i + 1] = data[i] + 1;
+ }
+ return GSL_SUCCESS;
+}
+
+int
+gsl_combination_prev (gsl_combination * c)
+{
+ /* Replaces c with the previous combination (in the standard
+ * lexicographical ordering). Returns GSL_FAILURE if there is no
+ * previous combination.
+ */
+ const size_t n = c->n;
+ const size_t k = c->k;
+ size_t *data = c->data;
+ size_t i;
+
+ if(k == 0)
+ {
+ return GSL_FAILURE;
+ }
+ i = k - 1;
+
+ while(i > 0 && data[i] == data[i-1] + 1)
+ {
+ i--;
+ }
+ if(i == 0 && data[i] == 0)
+ {
+ return GSL_FAILURE;
+ }
+ data[i++]--;
+ for(; i < k; i++)
+ {
+ data[i] = n - k + i;
+ }
+ return GSL_SUCCESS;
+}
+
+int
+gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src)
+{
+ const size_t src_n = src->n;
+ const size_t src_k = src->k;
+ const size_t dest_n = dest->n;
+ const size_t dest_k = dest->k;
+
+ if (src_n != dest_n || src_k != dest_k)
+ {
+ GSL_ERROR ("combination lengths are not equal", GSL_EBADLEN);
+ }
+
+ {
+ size_t j;
+
+ for (j = 0; j < src_k; j++)
+ {
+ dest->data[j] = src->data[j];
+ }
+ }
+
+ return GSL_SUCCESS;
+}
diff --git a/src/gsl/error.c b/src/gsl/error.c
new file mode 100644
index 0000000..ef4a45e
--- /dev/null
+++ b/src/gsl/error.c
@@ -0,0 +1,77 @@
+/* err/error.c
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gsl_errno.h"
+#include "gsl_message.h"
+
+gsl_error_handler_t * gsl_error_handler = NULL;
+
+static void no_error_handler (const char *reason, const char *file, int line, int gsl_errno);
+
+void
+gsl_error (const char * reason, const char * file, int line, int gsl_errno)
+{
+ if (gsl_error_handler)
+ {
+ (*gsl_error_handler) (reason, file, line, gsl_errno);
+ return ;
+ }
+
+ gsl_stream_printf ("ERROR", file, line, reason);
+
+ fflush (stdout);
+ fprintf (stderr, "Default GSL error handler invoked.\n");
+ fflush (stderr);
+
+ abort ();
+}
+
+gsl_error_handler_t *
+gsl_set_error_handler (gsl_error_handler_t * new_handler)
+{
+ gsl_error_handler_t * previous_handler = gsl_error_handler;
+ gsl_error_handler = new_handler;
+ return previous_handler;
+}
+
+
+gsl_error_handler_t *
+gsl_set_error_handler_off (void)
+{
+ gsl_error_handler_t * previous_handler = gsl_error_handler;
+ gsl_error_handler = no_error_handler;
+ return previous_handler;
+}
+
+static void
+no_error_handler (const char *reason, const char *file, int line, int gsl_errno)
+{
+ /* do nothing */
+ (void) reason;
+ (void) file;
+ (void) line;
+ (void) gsl_errno;
+ return;
+}
+
+
diff --git a/src/gsl/gsl_combination.h b/src/gsl/gsl_combination.h
new file mode 100644
index 0000000..ee13dfb
--- /dev/null
+++ b/src/gsl/gsl_combination.h
@@ -0,0 +1,76 @@
+/* combination/gsl_combination.h
+ * based on permutation/gsl_permutation.h by Brian Gough
+ *
+ * Copyright (C) 2001 Szymon Jaroszewicz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GSL_COMBINATION_H__
+#define __GSL_COMBINATION_H__
+
+#include <stdlib.h>
+#include "gsl_errno.h"
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+__BEGIN_DECLS
+
+struct gsl_combination_struct
+{
+ size_t n;
+ size_t k;
+ size_t *data;
+};
+
+typedef struct gsl_combination_struct gsl_combination;
+
+gsl_combination *gsl_combination_alloc (const size_t n, const size_t k);
+gsl_combination *gsl_combination_calloc (const size_t n, const size_t k);
+void gsl_combination_init_first (gsl_combination * c);
+void gsl_combination_init_last (gsl_combination * c);
+void gsl_combination_free (gsl_combination * c);
+int gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src);
+
+int gsl_combination_fread (FILE * stream, gsl_combination * c);
+int gsl_combination_fwrite (FILE * stream, const gsl_combination * c);
+int gsl_combination_fscanf (FILE * stream, gsl_combination * c);
+int gsl_combination_fprintf (FILE * stream, const gsl_combination * c, const char *format);
+
+size_t gsl_combination_n (const gsl_combination * c);
+size_t gsl_combination_k (const gsl_combination * c);
+size_t * gsl_combination_data (const gsl_combination * c);
+
+int gsl_combination_valid (gsl_combination * c);
+int gsl_combination_next (gsl_combination * c);
+int gsl_combination_prev (gsl_combination * c);
+
+static inline size_t
+gsl_combination_get (const gsl_combination * c, const size_t i)
+{
+ return c->data[i];
+}
+
+__END_DECLS
+
+#endif /* __GSL_COMBINATION_H__ */
diff --git a/src/gsl/gsl_errno.h b/src/gsl/gsl_errno.h
new file mode 100644
index 0000000..76a998c
--- /dev/null
+++ b/src/gsl/gsl_errno.h
@@ -0,0 +1,153 @@
+/* err/gsl_errno.h
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GSL_ERRNO_H__
+#define __GSL_ERRNO_H__
+
+#include <stdio.h>
+#include <errno.h>
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+__BEGIN_DECLS
+
+enum {
+ GSL_SUCCESS = 0,
+ GSL_FAILURE = -1,
+ GSL_CONTINUE = -2, /* iteration has not converged */
+ GSL_EDOM = 1, /* input domain error, e.g sqrt(-1) */
+ GSL_ERANGE = 2, /* output range error, e.g. exp(1e100) */
+ GSL_EFAULT = 3, /* invalid pointer */
+ GSL_EINVAL = 4, /* invalid argument supplied by user */
+ GSL_EFAILED = 5, /* generic failure */
+ GSL_EFACTOR = 6, /* factorization failed */
+ GSL_ESANITY = 7, /* sanity check failed - shouldn't happen */
+ GSL_ENOMEM = 8, /* malloc failed */
+ GSL_EBADFUNC = 9, /* problem with user-supplied function */
+ GSL_ERUNAWAY = 10, /* iterative process is out of control */
+ GSL_EMAXITER = 11, /* exceeded max number of iterations */
+ GSL_EZERODIV = 12, /* tried to divide by zero */
+ GSL_EBADTOL = 13, /* user specified an invalid tolerance */
+ GSL_ETOL = 14, /* failed to reach the specified tolerance */
+ GSL_EUNDRFLW = 15, /* underflow */
+ GSL_EOVRFLW = 16, /* overflow */
+ GSL_ELOSS = 17, /* loss of accuracy */
+ GSL_EROUND = 18, /* failed because of roundoff error */
+ GSL_EBADLEN = 19, /* matrix, vector lengths are not conformant */
+ GSL_ENOTSQR = 20, /* matrix not square */
+ GSL_ESING = 21, /* apparent singularity detected */
+ GSL_EDIVERGE = 22, /* integral or series is divergent */
+ GSL_EUNSUP = 23, /* requested feature is not supported by the hardware */
+ GSL_EUNIMPL = 24, /* requested feature not (yet) implemented */
+ GSL_ECACHE = 25, /* cache limit exceeded */
+ GSL_ETABLE = 26, /* table limit exceeded */
+ GSL_ENOPROG = 27, /* iteration is not making progress towards solution */
+ GSL_ENOPROGJ = 28, /* jacobian evaluations are not improving the solution */
+ GSL_ETOLF = 29, /* cannot reach the specified tolerance in F */
+ GSL_ETOLX = 30, /* cannot reach the specified tolerance in X */
+ GSL_ETOLG = 31, /* cannot reach the specified tolerance in gradient */
+ GSL_EOF = 32 /* end of file */
+} ;
+
+void gsl_error (const char * reason, const char * file, int line,
+ int gsl_errno);
+
+void gsl_stream_printf (const char *label, const char *file,
+ int line, const char *reason);
+
+const char * gsl_strerror (const int gsl_errno);
+
+typedef void gsl_error_handler_t (const char * reason, const char * file,
+ int line, int gsl_errno);
+
+typedef void gsl_stream_handler_t (const char * label, const char * file,
+ int line, const char * reason);
+
+gsl_error_handler_t *
+gsl_set_error_handler (gsl_error_handler_t * new_handler);
+
+gsl_error_handler_t *
+gsl_set_error_handler_off (void);
+
+gsl_stream_handler_t *
+gsl_set_stream_handler (gsl_stream_handler_t * new_handler);
+
+FILE * gsl_set_stream (FILE * new_stream);
+
+/* GSL_ERROR: call the error handler, and return the error code */
+
+#define GSL_ERROR(reason, gsl_errno) \
+ do { \
+ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
+ return gsl_errno ; \
+ } while (0)
+
+/* GSL_ERROR_VAL: call the error handler, and return the given value */
+
+#define GSL_ERROR_VAL(reason, gsl_errno, value) \
+ do { \
+ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
+ return value ; \
+ } while (0)
+
+/* GSL_ERROR_VOID: call the error handler, and then return
+ (for void functions which still need to generate an error) */
+
+#define GSL_ERROR_VOID(reason, gsl_errno) \
+ do { \
+ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
+ return ; \
+ } while (0)
+
+/* GSL_ERROR_NULL suitable for out-of-memory conditions */
+
+#define GSL_ERROR_NULL(reason, gsl_errno) GSL_ERROR_VAL(reason, gsl_errno, 0)
+
+/* Sometimes you have several status results returned from
+ * function calls and you want to combine them in some sensible
+ * way. You cannot produce a "total" status condition, but you can
+ * pick one from a set of conditions based on an implied hierarchy.
+ *
+ * In other words:
+ * you have: status_a, status_b, ...
+ * you want: status = (status_a if it is bad, or status_b if it is bad,...)
+ *
+ * In this example you consider status_a to be more important and
+ * it is checked first, followed by the others in the order specified.
+ *
+ * Here are some dumb macros to do this.
+ */
+#define GSL_ERROR_SELECT_2(a,b) ((a) != GSL_SUCCESS ? (a) : ((b) != GSL_SUCCESS ? (b) : GSL_SUCCESS))
+#define GSL_ERROR_SELECT_3(a,b,c) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_2(b,c))
+#define GSL_ERROR_SELECT_4(a,b,c,d) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_3(b,c,d))
+#define GSL_ERROR_SELECT_5(a,b,c,d,e) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_4(b,c,d,e))
+
+#define GSL_STATUS_UPDATE(sp, s) do { if ((s) != GSL_SUCCESS) *(sp) = (s);} while(0)
+
+__END_DECLS
+
+#endif /* __GSL_ERRNO_H__ */
diff --git a/src/gsl/gsl_message.h b/src/gsl/gsl_message.h
new file mode 100644
index 0000000..2061ddb
--- /dev/null
+++ b/src/gsl/gsl_message.h
@@ -0,0 +1,79 @@
+/* err/gsl_message.h
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GSL_MESSAGE_H__
+#define __GSL_MESSAGE_H__
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+__BEGIN_DECLS
+
+/* Provide a general messaging service for client use. Messages can
+ * be selectively turned off at compile time by defining an
+ * appropriate message mask. Client code which uses the GSL_MESSAGE()
+ * macro must provide a mask which is or'ed with the GSL_MESSAGE_MASK.
+ *
+ * The messaging service can be completely turned off
+ * by defining GSL_MESSAGING_OFF. */
+
+void gsl_message(const char * message, const char * file, int line,
+ unsigned int mask);
+
+#ifndef GSL_MESSAGE_MASK
+#define GSL_MESSAGE_MASK 0xffffffffu /* default all messages allowed */
+#endif
+
+unsigned int gsl_message_mask ;
+
+/* Provide some symolic masks for client ease of use. */
+
+enum {
+ GSL_MESSAGE_MASK_A = 1,
+ GSL_MESSAGE_MASK_B = 2,
+ GSL_MESSAGE_MASK_C = 4,
+ GSL_MESSAGE_MASK_D = 8,
+ GSL_MESSAGE_MASK_E = 16,
+ GSL_MESSAGE_MASK_F = 32,
+ GSL_MESSAGE_MASK_G = 64,
+ GSL_MESSAGE_MASK_H = 128
+} ;
+
+#ifdef GSL_MESSAGING_OFF /* throw away messages */
+#define GSL_MESSAGE(message, mask) do { } while(0)
+#else /* output all messages */
+#define GSL_MESSAGE(message, mask) \
+ do { \
+ if (mask & GSL_MESSAGE_MASK) \
+ gsl_message (message, __FILE__, __LINE__, mask) ; \
+ } while (0)
+#endif
+
+__END_DECLS
+
+#endif /* __GSL_MESSAGE_H__ */
+
+
diff --git a/src/gsl/init.c b/src/gsl/init.c
new file mode 100644
index 0000000..3a50c78
--- /dev/null
+++ b/src/gsl/init.c
@@ -0,0 +1,127 @@
+/* combination/init.c
+ * based on permutation/init.c by Brian Gough
+ *
+ * Copyright (C) 2001 Szymon Jaroszewicz
+ * Copyright (C) 2009 Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include "gsl_errno.h"
+#include "gsl_combination.h"
+
+gsl_combination *
+gsl_combination_alloc (const size_t n, const size_t k)
+{
+ gsl_combination * c;
+
+ if (n == 0)
+ {
+ GSL_ERROR_VAL ("combination parameter n must be positive integer",
+ GSL_EDOM, 0);
+ }
+ if (k > n)
+ {
+ GSL_ERROR_VAL ("combination length k must be an integer less than or equal to n",
+ GSL_EDOM, 0);
+ }
+ c = (gsl_combination *) malloc (sizeof (gsl_combination));
+
+ if (c == 0)
+ {
+ GSL_ERROR_VAL ("failed to allocate space for combination struct",
+ GSL_ENOMEM, 0);
+ }
+
+ if (k > 0)
+ {
+ c->data = (size_t *) malloc (k * sizeof (size_t));
+
+ if (c->data == 0)
+ {
+ free (c); /* exception in constructor, avoid memory leak */
+
+ GSL_ERROR_VAL ("failed to allocate space for combination data",
+ GSL_ENOMEM, 0);
+ }
+ }
+ else
+ {
+ c->data = 0;
+ }
+
+ c->n = n;
+ c->k = k;
+
+ return c;
+}
+
+gsl_combination *
+gsl_combination_calloc (const size_t n, const size_t k)
+{
+ size_t i;
+
+ gsl_combination * c = gsl_combination_alloc (n, k);
+
+ if (c == 0)
+ return 0;
+
+ /* initialize combination to identity */
+
+ for (i = 0; i < k; i++)
+ {
+ c->data[i] = i;
+ }
+
+ return c;
+}
+
+void
+gsl_combination_init_first (gsl_combination * c)
+{
+ const size_t k = c->k ;
+ size_t i;
+
+ /* initialize combination to identity */
+
+ for (i = 0; i < k; i++)
+ {
+ c->data[i] = i;
+ }
+}
+
+void
+gsl_combination_init_last (gsl_combination * c)
+{
+ const size_t k = c->k ;
+ size_t i;
+ size_t n = c->n;
+
+ /* initialize combination to identity */
+
+ for (i = 0; i < k; i++)
+ {
+ c->data[i] = n - k + i;
+ }
+}
+
+void
+gsl_combination_free (gsl_combination * c)
+{
+ if (c == NULL) return;
+ if (c->k > 0) free (c->data);
+ free (c);
+}
diff --git a/src/gsl/message.c b/src/gsl/message.c
new file mode 100644
index 0000000..a8961b0
--- /dev/null
+++ b/src/gsl/message.c
@@ -0,0 +1,37 @@
+/* err/message.c
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gsl_errno.h"
+#include "gsl_message.h"
+
+unsigned int gsl_message_mask = GSL_MESSAGE_MASK;
+
+void
+gsl_message (const char * reason, const char * file, int line,
+ unsigned int mask)
+{
+ if (mask & gsl_message_mask)
+ {
+ gsl_stream_printf ("MESSAGE", file, line, reason);
+ }
+}
diff --git a/src/gsl/stream.c b/src/gsl/stream.c
new file mode 100644
index 0000000..8cf2ef1
--- /dev/null
+++ b/src/gsl/stream.c
@@ -0,0 +1,65 @@
+/* err/stream.c
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gsl_errno.h"
+#include "gsl_message.h"
+
+FILE * gsl_stream = NULL ;
+gsl_stream_handler_t * gsl_stream_handler = NULL;
+
+void
+gsl_stream_printf (const char *label, const char *file, int line,
+ const char *reason)
+{
+ if (gsl_stream == NULL)
+ {
+ gsl_stream = stderr;
+ }
+ if (gsl_stream_handler)
+ {
+ (*gsl_stream_handler) (label, file, line, reason);
+ return;
+ }
+ fprintf (gsl_stream, "gsl: %s:%d: %s: %s\n", file, line, label, reason);
+
+}
+
+gsl_stream_handler_t *
+gsl_set_stream_handler (gsl_stream_handler_t * new_handler)
+{
+ gsl_stream_handler_t * previous_handler = gsl_stream_handler;
+ gsl_stream_handler = new_handler;
+ return previous_handler;
+}
+
+FILE *
+gsl_set_stream (FILE * new_stream)
+{
+ FILE * previous_stream;
+ if (gsl_stream == NULL) {
+ gsl_stream = stderr;
+ }
+ previous_stream = gsl_stream;
+ gsl_stream = new_stream;
+ return previous_stream;
+}
diff --git a/src/gsl/strerror.c b/src/gsl/strerror.c
new file mode 100644
index 0000000..398a132
--- /dev/null
+++ b/src/gsl/strerror.c
@@ -0,0 +1,100 @@
+/* err/strerror.c
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "gsl_errno.h"
+
+const char *
+gsl_strerror (const int gsl_errno)
+{
+ switch (gsl_errno)
+ {
+ case GSL_SUCCESS:
+ return "success" ;
+ case GSL_FAILURE:
+ return "failure" ;
+ case GSL_CONTINUE:
+ return "the iteration has not converged yet";
+ case GSL_EDOM:
+ return "input domain error" ;
+ case GSL_ERANGE:
+ return "output range error" ;
+ case GSL_EFAULT:
+ return "invalid pointer" ;
+ case GSL_EINVAL:
+ return "invalid argument supplied by user" ;
+ case GSL_EFAILED:
+ return "generic failure" ;
+ case GSL_EFACTOR:
+ return "factorization failed" ;
+ case GSL_ESANITY:
+ return "sanity check failed - shouldn't happen" ;
+ case GSL_ENOMEM:
+ return "malloc failed" ;
+ case GSL_EBADFUNC:
+ return "problem with user-supplied function";
+ case GSL_ERUNAWAY:
+ return "iterative process is out of control";
+ case GSL_EMAXITER:
+ return "exceeded max number of iterations" ;
+ case GSL_EZERODIV:
+ return "tried to divide by zero" ;
+ case GSL_EBADTOL:
+ return "specified tolerance is invalid or theoretically unattainable" ;
+ case GSL_ETOL:
+ return "failed to reach the specified tolerance" ;
+ case GSL_EUNDRFLW:
+ return "underflow" ;
+ case GSL_EOVRFLW:
+ return "overflow" ;
+ case GSL_ELOSS:
+ return "loss of accuracy" ;
+ case GSL_EROUND:
+ return "roundoff error" ;
+ case GSL_EBADLEN:
+ return "matrix/vector sizes are not conformant" ;
+ case GSL_ENOTSQR:
+ return "matrix not square" ;
+ case GSL_ESING:
+ return "singularity or extremely bad function behavior detected" ;
+ case GSL_EDIVERGE:
+ return "integral or series is divergent" ;
+ case GSL_EUNSUP:
+ return "the required feature is not supported by this hardware platform";
+ case GSL_EUNIMPL:
+ return "the requested feature is not (yet) implemented";
+ case GSL_ECACHE:
+ return "cache limit exceeded";
+ case GSL_ETABLE:
+ return "table limit exceeded";
+ case GSL_ENOPROG:
+ return "iteration is not making progress towards solution";
+ case GSL_ENOPROGJ:
+ return "jacobian evaluations are not improving the solution";
+ case GSL_ETOLF:
+ return "cannot reach the specified tolerance in F";
+ case GSL_ETOLX:
+ return "cannot reach the specified tolerance in X";
+ case GSL_ETOLG:
+ return "cannot reach the specified tolerance in gradient";
+ case GSL_EOF:
+ return "end of file";
+ default:
+ return "unknown error code" ;
+ }
+}
diff --git a/src/libqes/.gitignore b/src/libqes/.gitignore
new file mode 100644
index 0000000..b383896
--- /dev/null
+++ b/src/libqes/.gitignore
@@ -0,0 +1,12 @@
+# Editor temp files
+*.swp
+*.bak
+*~
+
+# compiled
+build
+*.o
+*.a
+*.so
+tags
+version
diff --git a/src/libqes/.travis.yml b/src/libqes/.travis.yml
new file mode 100644
index 0000000..aa41a19
--- /dev/null
+++ b/src/libqes/.travis.yml
@@ -0,0 +1,38 @@
+language: c
+
+env:
+ - BUILD_TYPE=Release
+ - BUILD_TYPE=Debug
+ - BUILD_TYPE=Coverage
+
+compiler:
+ - clang
+ - gcc
+
+install:
+ - sudo apt-get install lcov python-pip
+ - mkdir zlib && cd zlib
+ - wget http://zlib.net/zlib-1.2.8.tar.gz
+ - tar xvxf zlib-1.2.8.tar.gz
+ - cd zlib-1.2.8
+ - ./configure
+ - make
+ - sudo make install
+ - cd ../..
+ - sudo pip install cpp-coveralls
+ - git submodule update --init
+ - mkdir build
+ - mkdir target
+ - cd build
+
+script:
+ - cmake .. -DCMAKE_INSTALL_PREFIX=../target -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+ - make
+ - ctest --verbose
+ - make install
+ - test -f ../target/include/qes.h
+ - if [ $static == "TRUE" ] ; then test -f ../target/lib/libqes.a; else test -f ../target/lib/libqes.so ; fi
+
+after_success:
+ - cd ..
+ - if [ "$BUILD_TYPE" == "Coverage" ] ; then coveralls -e target -e test -e util -e zlib -E '.*\.h' -e build/CMakeFiles; fi
diff --git a/src/libqes/AUTHORS b/src/libqes/AUTHORS
new file mode 100644
index 0000000..cd220fe
--- /dev/null
+++ b/src/libqes/AUTHORS
@@ -0,0 +1 @@
+Kevin Murray <spam at kdmurray.id.au>
diff --git a/src/libqes/CMakeLists.txt b/src/libqes/CMakeLists.txt
new file mode 100644
index 0000000..bb91d87
--- /dev/null
+++ b/src/libqes/CMakeLists.txt
@@ -0,0 +1,154 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(libqes C)
+
+# Append cmake-modules to module path
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
+
+
+IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version")
+ FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/version" LIBQES_VERSION)
+ELSE()
+ # git describe as versioning
+ EXECUTE_PROCESS(COMMAND git describe
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE LIBQES_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF()
+
+#############################
+## Setup CMAKE Environment ##
+#############################
+
+# Set this before you include libqes as a CMake subproject, so that we know not
+# to add cmake to the install rule
+IF (LIBQES_AS_SUBMODULE)
+ SET(LIBQES_DONT_INSTALL True)
+ELSE()
+ SET(LIBQES_DONT_INSTALL False)
+ENDIF()
+
+OPTION(NO_OPENMP "Disable OpenMP" False)
+OPTION(NO_ZLIB "Disable zlib" False)
+# Shortcut to enable dev compile options
+OPTION(DEV "Enable developer warnings")
+IF (DEV)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined")
+ SET(CMAKE_BUILD_TYPE Coverage)
+ENDIF()
+
+IF (NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Release)
+ENDIF()
+
+MESSAGE(STATUS "${CMAKE_BUILD_TYPE} build of ${PROJECT_NAME} version: ${LIBQES_VERSION}")
+
+# Set output directories
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+# Include coverage module IFF out build type is Coverage to avoid bailing out
+# with unmet dependencies on Release builds, i.e. other peoples' computers
+IF (CMAKE_BUILD_TYPE STREQUAL "Coverage")
+ INCLUDE(CodeCoverage)
+ENDIF()
+
+# Testing
+ENABLE_TESTING()
+
+# Packaging
+SET(CPACK_GENERATOR "TGZ;TBZ2")
+INCLUDE(CPack)
+
+###############################
+## Find Packages and Headers ##
+###############################
+
+# Header/symbols
+INCLUDE(CheckSymbolExists)
+INCLUDE(CheckFunctionExists)
+INCLUDE(CheckLibraryExists)
+INCLUDE(CheckIncludeFiles)
+
+CHECK_SYMBOL_EXISTS(vasprintf stdio.h VASPRINTF_FOUND)
+CHECK_SYMBOL_EXISTS(asprintf stdio.h ASPRINTF_FOUND)
+CHECK_SYMBOL_EXISTS(getline stdio.h GETLINE_FOUND)
+CHECK_SYMBOL_EXISTS(strndup string.h STRNDUP_FOUND)
+
+IF (NOT ${NO_ZLIB})
+ FIND_PACKAGE(ZLIB 1.2.1 REQUIRED)
+ CHECK_LIBRARY_EXISTS(${ZLIB_LIBRARIES} gzbuffer "" GZBUFFER_FOUND)
+ELSE()
+ SET(ZLIB_FOUND FALSE)
+ SET(GZBUFFER_FOUND FALSE)
+ SET(ZLIB_C_FLAGS "")
+ SET(ZLIB_LIBRARIES "")
+ SET(ZLIB_INCLUDE_DIRS "")
+ MESSAGE(STATUS "Building without zlib")
+ENDIF()
+
+IF (NOT ${NO_OPENMP})
+ FIND_PACKAGE(OpenMP)
+ELSE()
+ SET(OPENMP_FOUND FALSE)
+ SET(OpenMP_C_FLAGS "")
+ MESSAGE(STATUS "Building without OpenMP")
+ENDIF()
+
+# Set dependency flags appropriately
+SET(LIBQES_DEPENDS_LIBS
+ ${LIBQES_DEPENDS_LIBS}
+ ${ZLIB_LIBRARIES})
+SET(LIBQES_DEPENDS_INCLUDE_DIRS
+ ${LIBQES_DEPENDS_INCLUDE_DIRS}
+ ${ZLIB_INCLUDE_DIRS})
+SET(LIBQES_DEPENDS_CFLAGS
+ ${LIBQES_DEPENDS_CFLAGS}
+ ${ZLIB_CFLAGS}
+ ${OpenMP_C_FLAGS})
+
+##########################
+## Set Compiler Options ##
+##########################
+
+# Set GCC-specific options
+IF (CMAKE_COMPILER_IS_GNUCC)
+ SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Woverride-init -Wnormalized=id -Wlogical-op")
+ EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
+ IF (${GCC_VERSION} VERSION_GREATER 4.9 OR ${GCC_VERSION} VERSION_EQUAL 4.9)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
+ ENDIF()
+ENDIF()
+
+# Set CFLAGS
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wstack-protector -Wfloat-equal")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wundef -Wpointer-arith -Wstrict-prototypes")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wmissing-prototypes -Wwrite-strings -Wredundant-decls")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wmissing-declarations -Wredundant-decls -Wnested-externs")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wbad-function-cast -Wswitch-enum -Winit-self")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wmissing-field-initializers -Wdeclaration-after-statement")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wold-style-definition -Waddress -Wmissing-noreturn ")
+SET(WEXTRA_FLAGS "${WEXTRA_FLAGS} -Wstrict-overflow=1 -Wextra -Warray-bounds -Wall")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBQES_DEPENDS_CFLAGS} -std=gnu99 ${WEXTRA_FLAGS}")
+
+SET(CMAKE_C_FLAGS_DEBUG "-ggdb")
+SET(CMAKE_C_FLAGS_RELEASE "-O3")
+
+# Set include dirs
+INCLUDE_DIRECTORIES(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/test
+ ${CMAKE_CURRENT_SOURCE_DIR}/test/tinytest
+ ${LIBQES_DEPENDS_INCLUDE_DIRS}
+ )
+
+# Set link dirs
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lib)
+
+# Traverse to library source and tests
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(test)
diff --git a/src/libqes/LICENSE b/src/libqes/LICENSE
new file mode 100644
index 0000000..bc08fe2
--- /dev/null
+++ b/src/libqes/LICENSE
@@ -0,0 +1,619 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
diff --git a/src/libqes/README.md b/src/libqes/README.md
new file mode 100644
index 0000000..ace5ed8
--- /dev/null
+++ b/src/libqes/README.md
@@ -0,0 +1,31 @@
+libqes
+======
+
+A C library for various bioinformatics-y tasks. Proper docs will come in time.
+For now, we have reasonable test coverage under `./test/` that demonstrate the
+API.
+
+###Tests:
+
+| Jenkins GNU/Linux | [![Build Status](http://biojenkins.anu.edu.au/job/libqes/badge/icon)](http://biojenkins.anu.edu.au/job/libqes/) |
+| ----------------- | --- |
+| Jenkins MinGW | [![Build Status](http://biojenkins.anu.edu.au/job/libqes-mingw/badge/icon)](http://biojenkins.anu.edu.au/job/libqes-mingw/) |
+| TravisCI | [![Build Status](https://travis-ci.org/kdmurray91/libqes.svg?branch=dev)](https://travis-ci.org/kdmurray91/libqes) |
+| Test Coverage | [![Coverage Status](https://img.shields.io/coveralls/kdmurray91/libqes.svg)](https://coveralls.io/r/kdmurray91/libqes?branch=master) |
+
+
+License
+=======
+
+![GPL logo](http://www.gnu.org/graphics/gplv3-127x51.png)
+
+All libqes source code is licensed under the GNU Public License version 3, or a
+later version at your preference. For license text, see `./gpl-3.0.txt` or
+[the GNU website here](http://www.gnu.org/licenses/gpl-3.0.html).
+
+The source of `tinytest`, located in `tests/tinytest`, is Copyright 2009-2012
+Nick Matthewson; `tinytest` is distributed under the 3-clause BSD license.
+`tinytest` is hosted at
+[Nick's github page](https://github.com/nmathewson/tinytest).
+
+`src/crc.[ch]` are from gnulib, and are licensed under the LGPL.
diff --git a/src/libqes/cmake-modules/CodeCoverage.cmake b/src/libqes/cmake-modules/CodeCoverage.cmake
new file mode 100644
index 0000000..749c979
--- /dev/null
+++ b/src/libqes/cmake-modules/CodeCoverage.cmake
@@ -0,0 +1,158 @@
+#
+# 2012-01-31, Lars Bilke
+# - Enable Code Coverage
+#
+# 2013-09-17, Joakim Söderberg
+# - Added support for Clang.
+# - Some additional usage instructions.
+#
+# USAGE:
+# 1. Copy this file into your cmake modules path.
+#
+# 2. Add the following line to your CMakeLists.txt:
+# INCLUDE(CodeCoverage)
+#
+# 3. Set compiler flags to turn off optimization and enable coverage:
+# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+#
+# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
+# which runs your test executable and produces a lcov code coverage report:
+# Example:
+# SETUP_TARGET_FOR_COVERAGE(
+# my_coverage_target # Name for custom target.
+# test_driver # Name of the test driver executable that runs the tests.
+# # NOTE! This should always have a ZERO as exit code
+# # otherwise the coverage generation will not complete.
+# coverage # Name of output directory.
+# )
+#
+# 4. Build a Debug build:
+# cmake -DCMAKE_BUILD_TYPE=Debug ..
+# make
+# make my_coverage_target
+#
+#
+
+# Check prereqs
+FIND_PROGRAM( GCOV_PATH gcov )
+FIND_PROGRAM( LCOV_PATH lcov )
+FIND_PROGRAM( GENHTML_PATH genhtml )
+FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
+
+
+
+SET(CMAKE_CXX_FLAGS_COVERAGE
+ "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C++ compiler during coverage builds."
+ FORCE)
+SET(CMAKE_C_FLAGS_COVERAGE
+ "${CMAKE_C_FLAGS_DEBUG} -g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C compiler during coverage builds."
+ FORCE)
+SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE)
+SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE)
+MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_COVERAGE
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
+
+IF(NOT GCOV_PATH)
+ MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
+ENDIF() # NOT GCOV_PATH
+
+IF(NOT CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_COMPILER_IS_GNUCXX)
+ # Clang version 3.0.0 and greater now supports gcov as well.
+ MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
+
+ IF(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+ ENDIF()
+ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX
+
+
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests.
+# MUST return ZERO always, even on errors.
+# If not, no coverage report will be created!
+# Param _outputname lcov output is generated as _outputname.info
+# HTML report is generated in _outputname/index.html
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname _coverdir)
+
+ IF(NOT LCOV_PATH)
+ MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
+ ENDIF() # NOT LCOV_PATH
+
+ IF(NOT GENHTML_PATH)
+ MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
+ ENDIF() # NOT GENHTML_PATH
+
+ # Setup target
+ ADD_CUSTOM_TARGET(${_targetname}
+
+ # Cleanup lcov
+ ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory ${_coverdir} --zerocounters
+
+ # Run tests
+ COMMAND ${_testrunner} ${ARGV4}
+
+ # Capturing lcov counters and generating report
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory ${_coverdir} --capture --output-file ${_outputname}.info
+ COMMAND ${GENHTML_PATH} --branch-coverage -o ${_outputname} ${_outputname}.info
+ COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info
+
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
+ )
+
+ # Show info where to find the report
+ ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+ COMMAND ;
+ COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
+ )
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests
+# Param _outputname cobertura output is generated as _outputname.xml
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
+
+ IF(NOT PYTHON_EXECUTABLE)
+ MESSAGE(FATAL_ERROR "Python not found! Aborting...")
+ ENDIF() # NOT PYTHON_EXECUTABLE
+
+ IF(NOT GCOVR_PATH)
+ MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
+ ENDIF() # NOT GCOVR_PATH
+
+ ADD_CUSTOM_TARGET(${_targetname}
+
+ # Run tests
+ ${_testrunner} ${ARGV3}
+
+ # Running gcovr
+ COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Running gcovr to produce Cobertura code coverage report."
+ )
+
+ # Show info where to find the report
+ ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+ COMMAND ;
+ COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
+ )
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA
diff --git a/src/libqes/cmake-modules/FindLIBQES.cmake b/src/libqes/cmake-modules/FindLIBQES.cmake
new file mode 100644
index 0000000..295217c
--- /dev/null
+++ b/src/libqes/cmake-modules/FindLIBQES.cmake
@@ -0,0 +1,83 @@
+# - Find libqes
+# Find the native libqes includes and library.
+# Once done this will define
+#
+# LIBQES_INCLUDE_DIRS - where to find qes.h, etc.
+# LIBQES_LIBRARIES - List of libraries when using libqes.
+# LIBQES_FOUND - True if libqes found.
+#
+# LIBQES_VERSION_STRING - The version of libqes found (x.y.z)
+# LIBQES_VERSION_MAJOR - The major version of libqes
+# LIBQES_VERSION_MINOR - The minor version of libqes
+# LIBQES_VERSION_PATCH - The patch version of libqes
+# LIBQES_VERSION_PREREL - The pre-release version of libqes
+# LIBQES_VERSION_GIT - The git version of libqes
+#
+# An includer may set LIBQES_ROOT to a libqes installation root to tell
+# this module where to look.
+
+#=============================================================================
+# Copyright 2014 Kevin Murray. Adapted from FindZLIB.cmake
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+set(_LIBQES_SEARCHES)
+
+# Search LIBQES_ROOT first if it is set.
+if(LIBQES_ROOT)
+ set(_LIBQES_SEARCH_ROOT PATHS ${LIBQES_ROOT} NO_DEFAULT_PATH)
+ list(APPEND _LIBQES_SEARCHES _LIBQES_SEARCH_ROOT)
+endif()
+
+# Normal search.
+set(_LIBQES_SEARCH_NORMAL
+ PATHS "$ENV{PROGRAMFILES}/libqes"
+ )
+list(APPEND _LIBQES_SEARCHES _LIBQES_SEARCH_NORMAL)
+
+# Try each search configuration.
+foreach(search ${_LIBQES_SEARCHES})
+ find_path(LIBQES_INCLUDE_DIR NAMES qes.h ${${search}} PATH_SUFFIXES include)
+ find_library(LIBQES_LIBRARY NAMES qes ${${search}} PATH_SUFFIXES lib)
+endforeach()
+
+mark_as_advanced(LIBQES_LIBRARY LIBQES_INCLUDE_DIR)
+# Handle version. Again, flogged from zlib
+if(LIBQES_INCLUDE_DIR AND EXISTS "${LIBQES_INCLUDE_DIR}/qes_config.h")
+ file(STRINGS "${LIBQES_INCLUDE_DIR}/qes_config.h" LIBQES_H REGEX "^#define LIBQES_VERSION \"[^\"]*\"")
+
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?([0-9]+).*$" "\\1" LIBQES_VERSION_MAJOR "${LIBQES_H}")
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.([0-9]+).*$" "\\1" LIBQES_VERSION_MINOR "${LIBQES_H}")
+ string(REGEX REPLACE "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBQES_VERSION_PATCH "${LIBQES_H}")
+ set(LIBQES_VERSION_STRING "${LIBQES_VERSION_MAJOR}.${LIBQES_VERSION_MINOR}.${LIBQES_VERSION_PATCH}")
+
+ # only append a EXTRA version if it exists:
+ set(LIBQES_VERSION_EXTRA "")
+ if( "${LIBQES_H}" MATCHES "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.[0-9]+(.+)\\+git.*$")
+ set(LIBQES_VERSION_PREREL "${CMAKE_MATCH_1}")
+ endif()
+ if( "${LIBQES_H}" MATCHES "^.*LIBQES_VERSION \"[Vv]?[0-9]+\\.[0-9]+\\.[0-9]+.*\\+git\\.(.+)$")
+ set(LIBQES_VERSION_git "${CMAKE_MATCH_1}")
+ endif()
+ set(LIBQES_VERSION_STRING "${LIBQES_VERSION_STRING}${LIBQES_VERSION_PREREL}")
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set LIBQES_FOUND to TRUE if
+# all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBQES REQUIRED_VARS LIBQES_LIBRARY LIBQES_INCLUDE_DIR
+ VERSION_VAR LIBQES_VERSION_STRING)
+
+if(LIBQES_FOUND)
+ set(LIBQES_INCLUDE_DIRS ${LIBQES_INCLUDE_DIR})
+ set(LIBQES_LIBRARIES ${LIBQES_LIBRARY})
+endif()
+
diff --git a/src/libqes/cmake-modules/GetGitRevisionDescription.cmake b/src/libqes/cmake-modules/GetGitRevisionDescription.cmake
new file mode 100644
index 0000000..c8d27f2
--- /dev/null
+++ b/src/libqes/cmake-modules/GetGitRevisionDescription.cmake
@@ -0,0 +1,130 @@
+# - Returns a version string from Git
+#
+# These functions force a re-configure on each git commit so that you can
+# trust the values of the variables in your build system.
+#
+# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
+#
+# Returns the refspec and sha hash of the current head revision
+#
+# git_describe(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe on the source tree, and adjusting
+# the output so that it tests false if an error occurs.
+#
+# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe --exact-match on the source tree,
+# and adjusting the output so that it tests false if there was no exact
+# matching tag.
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik at iastate.edu> <abiryan at ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+if(__get_git_revision_description)
+ return()
+endif()
+set(__get_git_revision_description YES)
+
+# We must run the following at "include" time, not at function call time,
+# to find the path to this module rather than the path to a calling list file
+get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+function(get_git_head_revision _refspecvar _hashvar)
+ set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+ while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
+ set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
+ get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
+ if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
+ # We have reached the root directory, we are not in git
+ set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+ set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+ set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+ endwhile()
+ # check if this is a submodule
+ if(NOT IS_DIRECTORY ${GIT_DIR})
+ file(READ ${GIT_DIR} submodule)
+ string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
+ get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
+ get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
+ endif()
+ set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
+ if(NOT EXISTS "${GIT_DATA}")
+ file(MAKE_DIRECTORY "${GIT_DATA}")
+ endif()
+
+ if(NOT EXISTS "${GIT_DIR}/HEAD")
+ return()
+ endif()
+ set(HEAD_FILE "${GIT_DATA}/HEAD")
+ configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
+
+ configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
+ "${GIT_DATA}/grabRef.cmake"
+ @ONLY)
+ include("${GIT_DATA}/grabRef.cmake")
+
+ set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
+ set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
+endfunction()
+
+function(git_describe _var)
+ if(NOT GIT_FOUND)
+ find_package(Git QUIET)
+ endif()
+ get_git_head_revision(refspec hash)
+ if(NOT GIT_FOUND)
+ set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+ if(NOT hash)
+ set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+
+ # TODO sanitize
+ #if((${ARGN}" MATCHES "&&") OR
+ # (ARGN MATCHES "||") OR
+ # (ARGN MATCHES "\\;"))
+ # message("Please report the following error to the project!")
+ # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
+ #endif()
+
+ #message(STATUS "Arguments to execute_process: ${ARGN}")
+
+ execute_process(COMMAND
+ "${GIT_EXECUTABLE}"
+ describe
+ ${hash}
+ ${ARGN}
+ WORKING_DIRECTORY
+ "${CMAKE_SOURCE_DIR}"
+ RESULT_VARIABLE
+ res
+ OUTPUT_VARIABLE
+ out
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT res EQUAL 0)
+ set(out "${out}-${res}-NOTFOUND")
+ endif()
+
+ set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
+
+function(git_get_exact_tag _var)
+ git_describe(out --exact-match ${ARGN})
+ set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
diff --git a/src/libqes/cmake-modules/GetGitRevisionDescription.cmake.in b/src/libqes/cmake-modules/GetGitRevisionDescription.cmake.in
new file mode 100644
index 0000000..888ce13
--- /dev/null
+++ b/src/libqes/cmake-modules/GetGitRevisionDescription.cmake.in
@@ -0,0 +1,38 @@
+#
+# Internal file for GetGitRevisionDescription.cmake
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik at iastate.edu> <abiryan at ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+set(HEAD_HASH)
+
+file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
+
+string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
+if(HEAD_CONTENTS MATCHES "ref")
+ # named branch
+ string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
+ if(EXISTS "@GIT_DIR@/${HEAD_REF}")
+ configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+ elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
+ configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+ set(HEAD_HASH "${HEAD_REF}")
+ endif()
+else()
+ # detached HEAD
+ configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
+endif()
+
+if(NOT HEAD_HASH)
+ file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
+ string(STRIP "${HEAD_HASH}" HEAD_HASH)
+endif()
diff --git a/src/libqes/cmake-modules/GitSemVer.cmake b/src/libqes/cmake-modules/GitSemVer.cmake
new file mode 100644
index 0000000..290b8dd
--- /dev/null
+++ b/src/libqes/cmake-modules/GitSemVer.cmake
@@ -0,0 +1,27 @@
+INCLUDE(GetGitRevisionDescription)
+
+function(GetGitSemVer _var)
+ get_git_head_revision(rev hash)
+ git_get_exact_tag(tag)
+
+ IF(NOT "${tag}" MATCHES "^-")
+ SET(vers "${tag}")
+ ELSE()
+ git_describe(gitdesc "--always")
+ if("${gitdesc}" MATCHES "^.+-.+-.+$")
+ STRING (REGEX REPLACE "-" " " gdlist ${gitdesc})
+ SEPARATE_ARGUMENTS(gdlist)
+ LIST(GET gdlist 0 tag)
+ LIST(GET gdlist 1 cmts_since_tag)
+ SET(vers "${tag}-${cmts_since_tag}-dirty")
+ ELSE()
+ SET(vers "dirty")
+ ENDIF()
+ ENDIF()
+
+ IF (NOT "${hash}" STREQUAL "")
+ STRING(SUBSTRING ${hash} 0 7 hash)
+ set(vers "${vers}+git=${hash}")
+ ENDIF()
+ set(${_var} ${vers} PARENT_SCOPE)
+endfunction()
diff --git a/src/libqes/src/CMakeLists.txt b/src/libqes/src/CMakeLists.txt
new file mode 100644
index 0000000..9e4e458
--- /dev/null
+++ b/src/libqes/src/CMakeLists.txt
@@ -0,0 +1,16 @@
+file(GLOB LIBQES_SOURCES qes_*.c)
+
+# Targets
+ADD_LIBRARY(qes_static STATIC ${LIBQES_SOURCES})
+SET_TARGET_PROPERTIES(qes_static PROPERTIES OUTPUT_NAME qes)
+TARGET_LINK_LIBRARIES(qes_static ${LIBQES_DEPENDS_LIBS})
+ADD_LIBRARY(qes SHARED ${LIBQES_SOURCES})
+TARGET_LINK_LIBRARIES(qes ${LIBQES_DEPENDS_LIBS})
+
+CONFIGURE_FILE(qes_config.h.in ${CMAKE_BINARY_DIR}/qes_config.h)
+FILE(GLOB LIBQES_HEADERS ${CMAKE_SOURCE_DIR}/src/*.h ${CMAKE_BINARY_DIR}/qes_config.h)
+
+IF (NOT LIBQES_DONT_INSTALL)
+ INSTALL(FILES ${LIBQES_HEADERS} DESTINATION "include")
+ INSTALL(TARGETS qes qes_static DESTINATION "lib")
+ENDIF()
diff --git a/src/libqes/src/crc.c b/src/libqes/src/crc.c
new file mode 100644
index 0000000..ee4ef56
--- /dev/null
+++ b/src/libqes/src/crc.c
@@ -0,0 +1,101 @@
+/* crc.c -- cyclic redundancy checks
+ Copyright (C) 2005-2006, 2009-2014 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson. */
+
+#include "crc.h"
+
+/* Table of CRCs of all 8-bit messages. Generated by running code
+ from RFC 1952 modified to print out the table. */
+static const uint32_t crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+ * The following function was extracted from RFC 1952 by Simon
+ * Josefsson. It was modified to avoid initial and final XOR, to use
+ * size_t for the buffer length, and to use the const keyword.
+ */
+uint32_t
+crc32_update_no_xor (uint32_t crc, const char *buf, size_t len)
+{
+ size_t n;
+
+ for (n = 0; n < len; n++)
+ crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
+
+ return crc;
+}
+
+uint32_t
+crc32_no_xor (const char *buf, size_t len)
+{
+ return crc32_update_no_xor (0L, buf, len);
+}
+
+uint32_t
+crc32_update (uint32_t crc, const char *buf, size_t len)
+{
+ return crc32_update_no_xor (crc ^ 0xffffffff, buf, len) ^ 0xffffffff;
+}
+
+uint32_t
+crc32 (const char *buf, size_t len)
+{
+ return crc32_update (0L, buf, len);
+}
diff --git a/src/libqes/src/crc.h b/src/libqes/src/crc.h
new file mode 100644
index 0000000..52c1747
--- /dev/null
+++ b/src/libqes/src/crc.h
@@ -0,0 +1,46 @@
+/* crc.h -- cyclic redundancy checks
+ Copyright (C) 2005, 2009-2014 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson. */
+
+#ifndef CRC_H
+# define CRC_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Compute CRC-32 value of LEN bytes long BUF, and return it. */
+uint32_t crc32 (const char *buf, size_t len);
+
+/* Incrementally update CRC-32 value CRC using LEN bytes long BUF. In
+ the first call, use 0 as the value for CRC. Return the updated
+ CRC-32 value. */
+uint32_t crc32_update (uint32_t crc, const char *buf, size_t len);
+
+/* Compute modified-CRC-32 value of LEN bytes long BUF, and return it.
+ The "modification" is to avoid the initial and final XOR operation.
+ Due to historic implementation errors, this variant is sometimes
+ used (i.e., in RFC 3961). */
+uint32_t crc32_no_xor (const char *buf, size_t len);
+
+/* Incrementally update modified-CRC-32 value CRC using LEN bytes long
+ BUF. In the first call, use 0 as the value for CRC. Return the
+ updated modified-CRC-32 value. The "modification" is to avoid the
+ initial and final XOR operation. Due to historic implementation
+ errors, this variant is sometimes used (i.e., in RFC 3961). */
+uint32_t crc32_update_no_xor (uint32_t crc, const char *buf, size_t len);
+
+#endif /* CRC_H */
diff --git a/src/libqes/src/qes.h b/src/libqes/src/qes.h
new file mode 100644
index 0000000..89138f3
--- /dev/null
+++ b/src/libqes/src/qes.h
@@ -0,0 +1,26 @@
+/*
+ * ==========================================================================
+ *
+ * Filename: qes.h
+ *
+ * Description: Some common sequence analysis stuff
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ===========================================================================
+ */
+
+#ifndef LIBQES_H
+#define LIBQES_H
+
+
+/* ##### HEADER FILE INCLUDES ########################################## */
+#include <qes_match.h>
+#include <qes_seqfile.h>
+#include <qes_seq.h>
+#include <qes_sequtil.h>
+#include <qes_str.h>
+#include <qes_util.h>
+#include <qes_file.h>
+
+#endif /* LIBQES_H */
diff --git a/src/libqes/src/qes_compat.c b/src/libqes/src/qes_compat.c
new file mode 100644
index 0000000..7c5e1b2
--- /dev/null
+++ b/src/libqes/src/qes_compat.c
@@ -0,0 +1,66 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_compat.c
+ *
+ * Description: Compatibility helpers for cross-platformness
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_compat.h"
+
+
+#ifndef STRNDUP_FOUND
+char *
+strndup(const char *s, size_t n)
+{
+ char *dest = malloc(n+1);
+ if (dest == NULL) return NULL;
+ strncpy(dest, s, n);
+ dest[n] = '\0';
+ return dest;
+}
+#endif
+
+#ifndef VASPRINTF_FOUND
+int vasprintf(char **ret, const char *format, va_list args)
+{
+ va_list copy;
+ int count;
+ va_copy(copy, args);
+
+ *ret = NULL;
+
+ count = vsnprintf(NULL, 0, format, args);
+ if (count >= 0) {
+ char *buffer = malloc(count + 1);
+ if (buffer == NULL) {
+ count = -1;
+ } else if ((count = vsnprintf(buffer, count + 1, format, copy)) < 0) {
+ free(buffer);
+ }
+ else {
+ *ret = buffer;
+ }
+ }
+ va_end(copy);
+
+ return count;
+}
+#endif
+
+#ifndef ASPRINTF_FOUND
+int asprintf(char **ret, const char *format, ...)
+{
+ va_list args;
+ int count;
+
+ va_start(args, format);
+ count = vasprintf(ret, format, args);
+ va_end(args);
+ return(count);
+}
+#endif
diff --git a/src/libqes/src/qes_compat.h b/src/libqes/src/qes_compat.h
new file mode 100644
index 0000000..33fc07b
--- /dev/null
+++ b/src/libqes/src/qes_compat.h
@@ -0,0 +1,29 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_compat.h
+ *
+ * Description: Compatibility helpers for cross-platformness
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_config.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+
+#ifndef STRNDUP_FOUND
+char *strndup(const char *s, size_t n);
+#endif
+
+#ifndef VASPRINTF_FOUND
+int vasprintf(char **ret, const char *format, va_list args);
+#endif
+
+#ifndef ASPRINTF_FOUND
+int asprintf(char **ret, const char *format, ...);
+#endif
diff --git a/src/libqes/src/qes_config.h.in b/src/libqes/src/qes_config.h.in
new file mode 100644
index 0000000..a8dc840
--- /dev/null
+++ b/src/libqes/src/qes_config.h.in
@@ -0,0 +1,76 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_config.h.in
+ *
+ * Description: Define various things from CMake.
+ *
+ * Created: 15/08/14 12:09:59
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_CONFIG_H
+#define QES_CONFIG_H
+
+#define LIBQES_VERSION "${LIBQES_VERSION}";
+#cmakedefine GETLINE_FOUND
+#cmakedefine STRNDUP_FOUND
+#cmakedefine ZLIB_FOUND
+#cmakedefine GZBUFFER_FOUND
+#cmakedefine OPENMP_FOUND
+#cmakedefine ASPRINTF_FOUND
+#cmakedefine VASPRINTF_FOUND
+
+/* Definitions to make changing fp type easy */
+#ifdef ZLIB_FOUND
+# include <zlib.h>
+# define QES_ZTYPE gzFile
+# define QES_ZOPEN gzopen
+# define QES_ZDOPEN gzdopen
+# define QES_ZCLOSE gzclose
+# define QES_ZREAD gzread
+# define QES_ZWRITE gzwrite
+# define QES_ZFLUSH(fp) gzflush(fp, Z_SYNC_FLUSH)
+# define QES_ZFPRINTF gzprintf
+# define QES_ZFPUTS gzputs
+# define QES_ZFPUTC gzputc
+# define QES_ZFGETS gzgets
+# define QES_ZFGETC gzgetc
+# define QES_ZFUNGETC gzungetc
+# define QES_ZERR gzerror
+# define QES_ZEOF gzeof
+#ifdef GZBUFFER_FOUND
+# define QES_ZBUFFER gzbuffer
+#endif
+# define QES_ZSEEK gzseek
+# define QES_ZTELL gztell
+# define QES_ZREWIND gzrewind
+#else
+# define QES_ZTYPE FILE*
+# define QES_ZOPEN fopen
+# define QES_ZCLOSE fclose
+# define QES_ZDOPEN fdopen
+# define QES_ZCLOSE fclose
+# define QES_ZREAD(fp, buf, ln) fread(buf, 1, ln, fp)
+# define QES_ZWRITE(fp, buf, ln) fwrite(buf, 1, ln, fp)
+# define QES_ZFLUSH fflush
+# define QES_ZFPRINTF fprintf
+# define QES_ZFPUTS(fp, s) fputs(s, fp)
+# define QES_ZFPUTC(fp, c) fputc(c, fp)
+# define QES_ZFGETS(fp, s, l) fgets(s, l, fp)
+# define QES_ZFGETC fgetc
+# define QES_ZFUNGETC fungetc
+# define QES_ZERR ferror
+# define QES_ZEOF feof
+# define QES_ZBUFFER(fp, sz) setvbuf(fp, NULL, _IOFBF, sz)
+# define QES_ZSEEK fseek
+# define QES_ZTELL ftell
+# define QES_ZREWIND rewind
+#endif
+
+#endif /* QES_CONFIG_H */
diff --git a/src/libqes/src/qes_file.c b/src/libqes/src/qes_file.c
new file mode 100644
index 0000000..25bcaad
--- /dev/null
+++ b/src/libqes/src/qes_file.c
@@ -0,0 +1,496 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_file.c
+ *
+ * Description: Compressed file IO
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_file.h"
+
+static int
+__qes_file_fill_buffer (struct qes_file *file)
+{
+ ssize_t res = 0;
+
+ if (!qes_file_ok(file)) {
+ return 0;
+ }
+ if (file->feof || file->eof) {
+ file->eof = 1;
+ return EOF;
+ }
+ res = QES_ZREAD(file->fp, file->buffer, QES_FILEBUFFER_LEN - 1);
+ if (res < 0) {
+ /* Errored */
+ return 0;
+ } else if (res == 0) {
+ /* At both buffer & file EOF */
+ file->eof = 1;
+ file->feof = 1;
+ return EOF;
+ } else if (res < (QES_FILEBUFFER_LEN) - 1) {
+ /* At file EOF */
+ file->feof = 1;
+ }
+ file->bufiter = file->buffer;
+ file->bufend = file->buffer + res;
+ file->bufend[0] = '\0';
+ return 1;
+}
+
+struct qes_file *
+qes_file_open_ (const char *path, const char *mode, qes_errhandler_func onerr,
+ const char *file, int line)
+{
+ struct qes_file *qf = NULL;
+
+ /* Error out with NULL */
+ if (path == NULL || mode == NULL || onerr == NULL || file == NULL) {
+ return NULL;
+ }
+
+ /* create file struct */
+ qf = qes_calloc(1, sizeof(*qf));
+ /* Open file, handling any errors */
+ qf->fp = QES_ZOPEN(path, mode);
+ if (qf->fp == NULL) {
+ (*onerr)("Opening file %s failed:\n%s\n", file, line,
+ path, strerror(errno));
+ qes_free(qf);
+ return(NULL);
+ }
+ qf->mode = qes_file_guess_mode(mode);
+ if (qf->mode == QES_FILE_MODE_UNKNOWN) {
+ QES_ZCLOSE(qf->fp);
+ qes_free(qf);
+ return NULL;
+ }
+ qf->buffer = qes_calloc_(sizeof(*qf->buffer), QES_FILEBUFFER_LEN,
+ onerr, file, line);
+ if (qf->buffer == NULL) {
+ QES_ZCLOSE(qf->fp);
+ qes_free(qf);
+ (*onerr)("Coudn't allocate buffer memory", file, line);
+ return NULL;
+ }
+ qf->bufiter = qf->buffer;
+ qf->buffer[0] = '\0';
+ qf->bufend = qf->buffer;
+ /* init struct fields */
+ qf->eof = 0;
+ qf->filepos = 0;
+ qf->path = strndup(path, QES_MAX_FN_LEN);
+ return(qf);
+}
+
+enum qes_file_mode
+qes_file_guess_mode (const char *mode)
+{
+ if (mode[0] == 'r') {
+ return QES_FILE_MODE_READ;
+ } else if(mode[0] == 'w' || mode[0] == 'a') {
+ return QES_FILE_MODE_WRITE;
+ }
+ return QES_FILE_MODE_UNKNOWN;
+}
+
+void
+qes_file_rewind (struct qes_file *file)
+{
+ if (qes_file_ok(file)) {
+ QES_ZSEEK(file->fp, 0, SEEK_SET);
+ file->filepos = 0;
+ file->eof = 0;
+ file->feof = 0;
+ file->bufiter = file->buffer;
+ file->bufend = file->buffer;
+ }
+}
+
+void
+qes_file_close_ (struct qes_file *file)
+{
+ if (file != NULL) {
+ if (file->fp != NULL) {
+ QES_ZCLOSE(file->fp);
+ }
+ qes_free(file->path);
+ qes_free(file->buffer);
+ file->bufiter = NULL;
+ file->bufend = NULL;
+ qes_free(file);
+ }
+}
+
+
+const char *
+qes_file_error (struct qes_file *file)
+{
+ int error = 0;
+ const char *errstr = "";
+
+ if (!qes_file_ok(file)) {
+ /* Never return NULL, or we'll SIGSEGV printf */
+ return "BAD FILE";
+ }
+#ifdef ZLIB_FOUND
+ errstr = gzerror(file->fp, &error);
+ if (error == Z_ERRNO) {
+ return strerror(errno);
+ }
+#else
+ error = ferror(file->fp);
+ if (error != 0) {
+ errstr = strerror(errno);
+ clearerr(file->fp);
+ }
+#endif
+ return errstr;
+}
+
+
+int
+qes_file_readable(struct qes_file *file)
+{
+ /* Here we check that reads won't fail. We refil if we need to. */
+ /* Can we possibly read from this file? */
+ if (!qes_file_ok(file) || file->mode == QES_FILE_MODE_UNKNOWN || \
+ file->mode == QES_FILE_MODE_WRITE || file->eof) {
+ return 0;
+ }
+ /* We can read from buffer */
+ if (file->bufiter < file->bufend && file->bufiter[0] != '\0') {
+ return 1;
+ }
+ /* Buffer needs a refil */
+ if (__qes_file_fill_buffer(file) != 0) {
+ /* we either successfully refilled, or are at EOF */
+ return file->eof ? EOF : 1;
+ } else {
+ /* No, we can't read */
+ return 0;
+ }
+}
+
+int
+qes_file_writable(struct qes_file *file)
+{
+ /* Here we check that reads won't fail. We refil if we need to. */
+ /* Can we possibly read from this file? */
+ if (!qes_file_ok(file) || file->mode == QES_FILE_MODE_UNKNOWN || \
+ file->mode == QES_FILE_MODE_READ) {
+ return 0;
+ }
+ /* TODO: be more rigorous here */
+ return 1;
+}
+
+int
+qes_file_peek(struct qes_file *file)
+{
+ if (!qes_file_ok(file) || qes_file_readable(file) == 0) {
+ return -2;
+ } else if (file->eof) {
+ return EOF;
+ }
+ return file->bufiter[0];
+}
+
+int
+qes_file_putstr(struct qes_file *stream, const struct qes_str *str)
+{
+ /* TODO: use the buffer in write mode */
+ return QES_ZWRITE(stream->fp, str->str, str->len);
+}
+
+int
+qes_file_puts(struct qes_file *file, const char *str)
+{
+ if (!qes_file_ok(file) || !qes_file_writable(file)) {
+ return -2;
+ }
+ return QES_ZFPUTS(file->fp, str);
+}
+
+int
+qes_file_putc(struct qes_file *file, const int chr)
+{
+ int res = 0;
+ if (!qes_file_ok(file) || !qes_file_writable(file)) {
+ return -2;
+ }
+ res = QES_ZFPUTC(file->fp, chr);
+ if (res != chr) {
+ return -1;
+ }
+ return 1;
+}
+
+
+int
+qes_file_getc(struct qes_file *file)
+{
+ if (!qes_file_ok(file) || qes_file_readable(file) == 0) {
+ return -2;
+ }
+ if (file->eof) {
+ return EOF;
+ }
+ return (file->bufiter++)[0];
+}
+
+ssize_t
+qes_file_getuntil_realloc_(struct qes_file *file, int delim, char **bufref,
+ size_t *sizeref, qes_errhandler_func onerr,
+ const char *src, const int line)
+{
+ size_t len = 0;
+ size_t tocpy = 0;
+ char *buf = NULL;
+ char *nextbuf = NULL;
+ char *end = NULL;
+ size_t size = 0;
+ int ret = 0;
+
+ if (bufref == NULL || !qes_file_ok(file) || sizeref == NULL) {
+ return -2;
+ }
+ if (file->eof) {
+ return EOF;
+ }
+ /* store local copies to stop dereferencing every time we need them */
+ buf = *bufref;
+ size = *sizeref;
+ /* Alloc the buffer if it's NULL */
+ if (buf == NULL) {
+ buf = qes_malloc_(__INIT_LINE_LEN * sizeof(*buf), onerr, src, line);
+ size = __INIT_LINE_LEN;
+ buf[0] = '\0';
+ }
+ /* Set nextbuf AFTER we may/may not have alloced buf above
+ * In case we error out below, we always set bufref = buf here, as
+ * then we don't lose the memory alloced above */
+ *bufref = nextbuf = buf;
+ /* Read until delim is in file->buffer, filling buffer */
+ while ((end = memchr(file->bufiter, delim, file->bufend - file->bufiter))
+ == NULL) {
+ /* copy the remainder of the buffer */
+ tocpy = file->bufend - file->bufiter;
+ len += tocpy;
+ while (len + 1 >= size) {
+ size = qes_roundupz(size);
+ buf = qes_realloc_(buf, sizeof(*buf) * size, onerr, src, line);
+ if (buf == NULL) {
+ /* We bail out here, and *bufref is untouched. This means we
+ * can check for errors, and free *bufref from the calling
+ * function */
+ return -2;
+ }
+ *bufref = buf;
+ }
+ /* set to the correct position in the NEW buf, maybe after realloc */
+ nextbuf = buf + len - tocpy;
+ memcpy(nextbuf, file->bufiter, tocpy);
+ /* Update pointers to point to their respective heads */
+ nextbuf += tocpy;
+ file->bufiter += tocpy;
+ /* Null-terminate buf */
+ buf[len] = '\0';
+ /* file->buffer should now be empty, so fill 'er up! */
+ ret = __qes_file_fill_buffer(file);
+ if (ret == 0) {
+ /* Couln't fill, error out */
+ return -2;
+ } else if (ret == EOF) {
+ /* EOF time */
+ break;
+ }
+ }
+ if (end != NULL) {
+ /* We've got the delimter in the buffer */
+ tocpy = end + 1 - file->bufiter; /* +1 includes the delimiter */
+ } else if (file->bufiter < file->bufend) {
+ /* No delimiter, but we return what we have. */
+ tocpy = file->bufend - file->bufiter;
+ } else {
+ /* Nothign left at all */
+ file->eof = 1;
+ goto done;
+ }
+ /* we need to ensure that we still have enough room.
+ * This happens as above */
+ len += tocpy;
+ while (len + 1 >= size) {
+ size = qes_roundupz(size + 1);
+ buf = qes_realloc_(buf, sizeof(*buf) * size, onerr, src, line);
+ if (buf == NULL) {
+ /* We bail out here, and *bufref is untouched. This means we
+ * can check for errors, and free *bufref from the calling
+ * function */
+ return -2;
+ }
+ *bufref = buf;
+ }
+ nextbuf = buf + len - tocpy;
+ memcpy(nextbuf, file->bufiter, tocpy);
+ file->bufiter += tocpy;
+ /* We don't bother updating nextbuf, as this was our final copy to buf */
+ goto done;
+done:
+ /* restore/update referred values */
+ *bufref = buf;
+ *sizeref = size;
+ if (len > 0) {
+ /* We have something to return, so return its length */
+ file->filepos += len;
+ buf[len] = '\0';
+ return len;
+ } else if (file->eof) {
+ return EOF;
+ } else {
+ /* Shouldn't reach here! */
+ return -2;
+ }
+}
+#define qes_file_getuntil_realloc(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, QES_DEFAULT_ERR_FN, \
+ __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errnil(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errnil, __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errprint(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errprint, __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errprintexit(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errprintexit, __FILE__, \
+ __LINE__)
+
+
+/* === FUNCTION =============================================================
+ Name: qes_file_readline_realloc
+ Description: Read a line from `file` into a `char *` pointed to by `buf`.
+ This function has the added benefit of `realloc`-ing `buf`
+ to the next highest base-2 power, if we run out of space.
+ If it is realloced, `(*size)` is updated to the new buffer
+ size. DON'T USE ON STACK BUFFERS.
+ Returns: ssize_t set to either the length of the line copied to `*buf`,
+ or one of -1 (EOF) or -2 (error).
+ * ==========================================================================*/
+ssize_t
+qes_file_readline_realloc_ (struct qes_file *file, char **buf, size_t *size,
+ qes_errhandler_func onerr, const char *src, const int line)
+{
+ return qes_file_getuntil_realloc_(file, '\n', buf, size, onerr, src, line);
+}
+#define qes_file_readline_realloc(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, QES_DEFAULT_ERR_FN, __FILE__, \
+ __LINE__)
+#define qes_file_readline_realloc_errnil(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errnil, __FILE__, __LINE__)
+#define qes_file_readline_realloc_errprint(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errprint, __FILE__, __LINE__)
+#define qes_file_readline_realloc_errprintexit(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errprintexit, __FILE__, __LINE__)
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_getuntil
+Paramters: struct qes_file *file: File to read
+ const int delim: Delimiter char.
+Description: Reads ``file`` into ``dest`` until ``delim`` is found or
+ ``maxlen - `` bytes have been read. ``delim`` is copied into
+ ``dest``! ``delim`` can be EOF for "read until EOF", or any
+ other thing that fits in a ``char``.
+Returns: ssize_t: EOF, -2 (error) or size of data read.
+ *===========================================================================*/
+ssize_t
+qes_file_getuntil (struct qes_file *file, const int delim, char *dest,
+ size_t maxlen)
+{
+ size_t len = 0;
+ char *nextbuf = dest;
+ size_t tocpy = 0;
+ char *end = NULL;
+ int ret = 0 ;
+ if (dest == NULL || !qes_file_ok(file) || maxlen < 1 || delim > 255) {
+ /* EOF is normally == -1, so use -2 to differentiate them */
+ return -2;
+ }
+ /* For detailed commentary, see qes_file_getuntil_realloc */
+ /* Get out early if we're at EOF already */
+ if (file->eof) {
+ return EOF;
+ }
+ while ((end = memchr(file->bufiter, delim, file->bufend - file->bufiter))
+ == NULL) {
+ tocpy = file->bufend - file->bufiter;
+ if (len + tocpy >= maxlen) {
+ /* + 1 because we always leave space for \0 */
+ tocpy += maxlen - (len + tocpy + 1);
+ }
+ len += tocpy;
+ memcpy(nextbuf, file->bufiter, tocpy);
+ nextbuf += tocpy;
+ file->bufiter += tocpy;
+ dest[len] = '\0'; /* Null-terminate buf */
+ ret = __qes_file_fill_buffer(file);
+ if (ret == 0) {
+ return -2;
+ } else if (ret == EOF) {
+ break;
+ }
+ }
+ if (end != NULL) {
+ tocpy = (end - file->bufiter) + 1; /* +1 includes the delimiter */
+ } else if (file->bufiter < file->bufend) {
+ tocpy = file->bufend - file->bufiter;
+ } else {
+ /* Nothign left at all */
+ file->eof = 1;
+ goto done;
+ }
+ if (len + tocpy >= maxlen) {
+ /* maxlen - 1 because we always leave space for \0 */
+ tocpy += maxlen - (len + tocpy + 1);
+ }
+ memcpy(nextbuf, file->bufiter, tocpy);
+ len += tocpy;
+ file->bufiter += tocpy;
+ goto done;
+done:
+ if (len > 0) {
+ file->filepos += len;
+ dest[len] = '\0';
+ return len;
+ } else if (file->eof) {
+ return EOF;
+ } else {
+ return -2;
+ }
+}
+
+ssize_t
+qes_file_readline (struct qes_file *file, char *dest, size_t maxlen)
+{
+ return qes_file_getuntil(file, '\n', dest, maxlen);
+}
+
+ssize_t
+qes_file_readline_str (struct qes_file *file, struct qes_str *str)
+{
+ ssize_t len = 0;
+
+ if (file == NULL || !qes_str_ok(str)) {
+ return -2; /* ERROR, not EOF */
+ }
+ len = qes_file_readline_realloc(file, &(str->str), &(str->capacity));
+ if (len < 0) {
+ qes_str_nullify(str);
+ return len;
+ }
+ str->len = len;
+ return len;
+}
diff --git a/src/libqes/src/qes_file.h b/src/libqes/src/qes_file.h
new file mode 100644
index 0000000..6e8f458
--- /dev/null
+++ b/src/libqes/src/qes_file.h
@@ -0,0 +1,213 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_file.h
+ *
+ * Description: Compressed file IO
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_FILE_H
+#define QES_FILE_H
+
+#include <qes_util.h>
+#include <qes_str.h>
+
+enum qes_file_mode {
+ QES_FILE_MODE_UNKNOWN,
+ QES_FILE_MODE_READ,
+ QES_FILE_MODE_WRITE
+};
+
+struct qes_file {
+ QES_ZTYPE fp;
+ char *path;
+ char *buffer;
+ char *bufiter;
+ char *bufend;
+ off_t filepos;
+ enum qes_file_mode mode;
+ /* Is the fp at EOF, AND do we have nothing left to copy from the buffer */
+ int eof;
+ /* Is the fp at EOF */
+ int feof;
+};
+
+/* qes_file_open:
+ Create a `struct qes_file` and open `path` with mode `mode` and
+ errorhandler `onerr`
+ */
+struct qes_file *qes_file_open_(const char *path,
+ const char *mode,
+ qes_errhandler_func onerr,
+ const char *file,
+ int line);
+#define qes_file_open(pth, mod) \
+ qes_file_open_(pth, mod, QES_DEFAULT_ERR_FN, __FILE__, __LINE__)
+#define qes_file_open_errnil(pth, mod) \
+ qes_file_open_(pth, mod, errnil, __FILE__, __LINE__)
+#define qes_file_open_errprint(pth, mod) \
+ qes_file_open_(pth, mod, errprint, __FILE__, __LINE__)
+#define qes_file_open_errprintexit(pth, mod) \
+ qes_file_open_(pth, mod, errprintexit, __FILE__, __LINE__)
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_close
+Paramters: struct qes_file *file: file to close.
+Description: Closes the file pointer in ``file``, frees dynamically
+ allocated members of ``file`` and sets ``file`` to NULL.
+Returns: void
+ *===========================================================================*/
+void qes_file_close_ (struct qes_file *file);
+#define qes_file_close(file) do { \
+ qes_file_close_ (file); \
+ file = NULL; \
+ } while(0)
+
+int qes_file_readable (struct qes_file *file);
+int qes_file_writable (struct qes_file *file);
+enum qes_file_mode qes_file_guess_mode
+ (const char *mode);
+
+void qes_file_rewind (struct qes_file *file);
+int qes_file_peek (struct qes_file *file);
+
+int qes_file_putstr (struct qes_file *stream,
+ const struct qes_str *str);
+int qes_file_puts (struct qes_file *file,
+ const char *str);
+int qes_file_putc (struct qes_file *stream,
+ const int chr);
+int qes_file_getc (struct qes_file *file);
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_readline
+Paramters: struct qes_file *file: File to read
+ char *dest: Destination buffer
+ size_t maxlen: size of destination buffer
+Description: Reads at most ``maxlen - 1`` bytes of the next '\n' delimited
+ line into ``dest``, and null- terminates ``dest``. The '\n' is
+ copied, and therefore counts towards ``strlen()`` of ``dest``.
+Returns: ssize_t: EOF, -2 (error), or length of bytes copied, i.e.
+ ``strlen(dest);``
+ *===========================================================================*/
+ssize_t qes_file_readline (struct qes_file *file,
+ char *dest,
+ size_t maxlen);
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_readline_str
+Paramters: struct qes_file *file: File to read.
+ struct qes_str *str: struct qes_str object to read into.
+Description: Convenience wrapper around qes_file_readline_realloc, which
+ reads a line into a struct qes_str object, passing str->str to
+ and str->capacity to qes_file_readline_realloc.
+Returns: ssize_t set to either the length of the line copied to the
+ struct qes_str, or one of -1 (EOF) or -2 (error).
+* ===========================================================================*/
+ssize_t qes_file_readline_str (struct qes_file *file,
+ struct qes_str *str);
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_getuntil
+Paramters: struct qes_file *file: File to read
+ const int delim: Delimiter char.
+Description: Reads ``file`` into ``dest`` until ``delim`` is found or
+ ``maxlen - `` bytes have been read. ``delim`` is copied into
+ ``dest``! ``delim`` can be EOF for "read until EOF", or any
+ other thing that fits in a ``char``.
+Returns: ssize_t: EOF, -2 (error) or size of data read.
+ *===========================================================================*/
+ssize_t qes_file_getuntil (struct qes_file *file,
+ const int delim,
+ char *dest,
+ size_t maxlen);
+
+/*=== FUNCTION ============================================================*
+Name: qes_file_getuntil_realloc
+Paramters: qes_file *file: File to read.
+ int delim: Delimiter char.
+ char **bufref: reference to a `char *` containing the buffer.
+ Must not refer to a ``char[]`` that cannot be resized with
+ ``realloc``.
+ size *sizeref: Reference to a variable tracking the allocated
+ size of the ``char *`` referred to by ``bufref``.
+Description: Read a string from `file` into a
+ `char *` pointed to by
+ `bufref` up to and inclding the character ``delim``. This
+ function has the added benefit of `realloc`-ing `*bufref` to
+ the next highest base-2 power, if we run out of space. If it
+ is realloced, `(*sizeref)` is updated to the new buffer size.
+Returns: ssize_t set to either the length of the line copied to
+ `*bufref`, or one of -1 (EOF) or -2 (error).
+*============================================================================*/
+ssize_t qes_file_getuntil_realloc_
+ (struct qes_file *file,
+ int delim,
+ char **bufref,
+ size_t *sizeref,
+ qes_errhandler_func onerr,
+ const char *src,
+ const int line);
+
+#define qes_file_getuntil_realloc(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, QES_DEFAULT_ERR_FN, \
+ __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errnil(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errnil, __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errprint(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errprint, __FILE__, __LINE__)
+#define qes_file_getuntil_realloc_errprintexit(fp, dlm, buf, sz) \
+ qes_file_getuntil_realloc_(fp, dlm, buf, sz, errprintexit, __FILE__, \
+ __LINE__)
+
+
+/* === FUNCTION =============================================================
+ Name: qes_file_readline_realloc
+ Description: Read a line from `file` into a `char *` pointed to by `buf`.
+ This function has the added benefit of `realloc`-ing `buf`
+ to the next highest base-2 power, if we run out of space.
+ If it is realloced, `(*size)` is updated to the new buffer
+ size. DON'T USE ON STACK BUFFERS.
+ Returns: ssize_t set to either the length of the line copied to `*buf`,
+ or one of -1 (EOF) or -2 (error).
+ * ==========================================================================*/
+ssize_t qes_file_readline_realloc_
+ (struct qes_file *file,
+ char **buf,
+ size_t *size,
+ qes_errhandler_func onerr,
+ const char *src,
+ const int line);
+#define qes_file_readline_realloc(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, QES_DEFAULT_ERR_FN, __FILE__, \
+ __LINE__)
+#define qes_file_readline_realloc_errnil(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errnil, __FILE__, __LINE__)
+#define qes_file_readline_realloc_errprint(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errprint, __FILE__, __LINE__)
+#define qes_file_readline_realloc_errprintexit(fp, buf, sz) \
+ qes_file_readline_realloc_(fp, buf, sz, errprintexit, __FILE__, __LINE__)
+
+
+const char *qes_file_error (struct qes_file *file);
+
+static inline int
+qes_file_ok (const struct qes_file *qf)
+{
+ /* qes_file_ok just check we won't dereference NULLs, so we check pointer
+ * NULLness for all pointers we care about in current modes. Which, unless
+ * we're Write-only, is all of them */
+ return qf != NULL && \
+ qf->fp != NULL && \
+ qf->bufiter != NULL && \
+ qf->buffer != NULL;
+}
+
+
+#endif /* QES_FILE_H */
diff --git a/src/libqes/src/qes_libgnu.c b/src/libqes/src/qes_libgnu.c
new file mode 100644
index 0000000..4ac1497
--- /dev/null
+++ b/src/libqes/src/qes_libgnu.c
@@ -0,0 +1,16 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_libgnu.c
+ * Description: Functions required from gnulib
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_libgnu.h"
+
+#ifndef ZLIB_FOUND
+# include "crc.c"
+#endif
diff --git a/src/libqes/src/qes_libgnu.h b/src/libqes/src/qes_libgnu.h
new file mode 100644
index 0000000..3993a42
--- /dev/null
+++ b/src/libqes/src/qes_libgnu.h
@@ -0,0 +1,28 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_libgnu.h
+ * Description: Functions required from gnulib
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_LIBGNU_H
+#define QES_LIBGNU_H
+
+#include "qes_config.h"
+
+/* This file and qes_libgnu.c are designed to allow us to keep the sources of
+ * the gnulib functions intact and in their original seperate form. */
+
+#ifndef ZLIB_FOUND
+# include "crc.h"
+#else
+# include <zlib.h>
+/* Cast is to avoid a difference in signed-ness in the two implementations. */
+# define crc32_update(c, b, l) crc32(c, (const unsigned char *)b, l)
+#endif
+
+#endif /* QES_LIBGNU_H */
diff --git a/src/libqes/src/qes_log.c b/src/libqes/src/qes_log.c
new file mode 100644
index 0000000..6c19a1d
--- /dev/null
+++ b/src/libqes/src/qes_log.c
@@ -0,0 +1,251 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_log.c
+ *
+ * Description: Logging module of libngs2
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_log.h"
+
+
+struct qes_logger *
+qes_logger_create(void)
+{
+ return qes_calloc(1, sizeof(struct qes_logger));
+}
+
+int
+qes_logger_init(struct qes_logger *logger,
+ const char *name,
+ enum qes_log_level level)
+{
+ if (logger == NULL) return 1;
+
+ if (name != NULL) {
+ logger->name = strdup(name);
+ } else if (logger->name != NULL) {
+ free(logger->name);
+ logger->name = NULL;
+ }
+ logger->level = level;
+ return 0;
+}
+
+int
+qes_logger_add_destination_formatted(struct qes_logger *logger,
+ FILE *stream,
+ enum qes_log_level level,
+ char *(*formatter)(struct qes_log_entry *entry))
+{
+ struct qes_log_destination *new = NULL;
+ size_t new_sz = logger->n_destinations + 1;
+
+ new = qes_realloc(logger->destinations,
+ new_sz * sizeof(*logger->destinations));
+ if (new == NULL) {
+ return 1;
+ }
+ logger->destinations = new;
+ logger->n_destinations = new_sz;
+ /* For ease of reference, save the ptr to the (new) final struct in
+ * the array */
+ new = &new[new_sz - 1];
+ new->stream = stream;
+ new->level = level;
+ new->formatter = formatter;
+ return 0;
+}
+
+void
+_qes_logger_destroy(struct qes_logger *logger)
+{
+ if (logger != NULL) {
+ qes_free(logger->name);
+ qes_free(logger->destinations);
+ qes_free(logger);
+ }
+}
+
+struct qes_log_entry *
+qes_log_entry_create(void)
+{
+ return qes_calloc(1, sizeof(struct qes_log_entry));
+}
+
+int
+qes_log_entry_init(struct qes_log_entry *entry,
+ enum qes_log_level level,
+ const char *message)
+{
+ if (entry == NULL || message == NULL) return -1;
+
+ entry->level = level;
+ entry->message = strdup(message);
+ return 0;
+}
+
+int
+qes_log_entry_format_va(struct qes_log_entry *entry,
+ enum qes_log_level level,
+ const char *format,
+ va_list args)
+{
+ int res = 0;
+ char *message = NULL;
+
+ /* Format the error message w/ user input */
+ res = vasprintf(&message, format, args);
+ if (res < 1) {
+ /* Alloc inside vasprintf failed */
+ return 1;
+ }
+ /* Make the entry struct */
+ res = qes_log_entry_init(entry, level, message);
+ free(message);
+ return res;
+}
+
+int
+qes_log_entry_format(struct qes_log_entry *entry,
+ enum qes_log_level level,
+ const char *format,
+ ...)
+{
+ va_list args;
+ int res = 0;
+
+ /* Format the error message w/ user input */
+ va_start(args, format);
+ res = qes_log_entry_format_va(entry, level, format, args);
+ va_end(args);
+ return res;
+}
+
+void
+_qes_log_entry_destroy(struct qes_log_entry *entry)
+{
+ if (entry != NULL) {
+ qes_free(entry->message);
+ qes_free(entry);
+ }
+}
+void qes_log_entry_clear(struct qes_log_entry *entry)
+{
+ if (entry != NULL) {
+ qes_free(entry->message);
+ entry->level = QES_LOG_DEBUG;
+ }
+}
+
+int
+qes_logger_write_entry(struct qes_logger *logger,
+ struct qes_log_entry *entry)
+{
+ size_t iii;
+ int res;
+
+ if (logger == NULL || entry == NULL) return 1;
+
+ /* Message is to unimportant for this logger */
+ if (logger->level > entry->level) return 0;
+
+ for (iii = 0; iii < logger->n_destinations; iii++) {
+ char *formatted = NULL;
+ struct qes_log_destination *dest = &logger->destinations[iii];
+
+ /* Message is to unimportant for this destination */
+ if (dest->level > entry->level) continue;
+
+ formatted = dest->formatter(entry);
+ if (formatted == NULL) return 1;
+ res = fprintf(dest->stream, "%s", formatted);
+ fflush(dest->stream);
+ qes_free(formatted);
+ if (res < 0) return 1;
+ }
+ return 0;
+}
+
+int
+qes_log_message(struct qes_logger *logger,
+ enum qes_log_level level,
+ const char *message)
+{
+ struct qes_log_entry entry;
+ int res = 0;
+
+ res = qes_log_entry_format(&entry, level, "%s", message);
+ if (res != 0) return res;
+ res = qes_logger_write_entry(logger, &entry);
+ qes_log_entry_clear(&entry);
+ return res;
+}
+
+int
+qes_log_format(struct qes_logger *logger,
+ enum qes_log_level level,
+ const char *format,
+ ...)
+{
+ struct qes_log_entry entry;
+ va_list args;
+ int res = 0;
+
+ va_start(args, format);
+ res = qes_log_entry_format_va(&entry, level, format, args);
+ va_end(args);
+ if (res != 0) return res;
+ res = qes_logger_write_entry(logger, &entry);
+ qes_log_entry_clear(&entry);
+ return res;
+}
+
+char *
+qes_log_formatter_plain(struct qes_log_entry *entry)
+{
+ /* In the plain-text case, we just pass the message as is. */
+ if (entry == NULL) return NULL;
+ if (entry->message == NULL) return NULL;
+ return strdup(entry->message);
+}
+
+char *
+qes_log_formatter_pretty(struct qes_log_entry *entry)
+{
+ char *buf = NULL;
+ const char *colour = ANSIRST;
+ const char *reset = ANSIRST;
+ char marker = ' ';
+ int res = 0;
+
+ if (entry == NULL || entry->message == NULL) return NULL;
+
+ if (entry->level <= QES_LOG_DEBUG) {
+ marker = '.';
+ colour = ANSIBEG ATDIM FGCYN BGBLK ANSIEND;
+ reset = "";
+ } else if (entry->level <= QES_LOG_INFO) {
+ marker = '*';
+ colour = ANSIBEG ATNRM FGGRN BGBLK ANSIEND;
+ } else if (entry->level <= QES_LOG_WARNING) {
+ marker = '!';
+ colour = ANSIBEG ATULN FGYEL BGBLK ANSIEND;
+ } else if (entry->level <= QES_LOG_ERROR) {
+ marker = 'E';
+ colour = ANSIBEG ATBLD FGMAG BGBLK ANSIEND;
+ } else {
+ marker = 'F';
+ colour = ANSIBEG ATBLD ATBNK FGRED BGBLK ANSIEND;
+ }
+ res = asprintf(&buf, "%s[%c] %s%s", colour, marker, entry->message, reset);
+ if (res > 0) {
+ return buf;
+ } else {
+ return NULL;
+ }
+}
diff --git a/src/libqes/src/qes_log.h b/src/libqes/src/qes_log.h
new file mode 100644
index 0000000..614e0ad
--- /dev/null
+++ b/src/libqes/src/qes_log.h
@@ -0,0 +1,150 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_log.h
+ *
+ * Description: Logging module of libngs2
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_LOG_H
+#define QES_LOG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <qes_util.h>
+
+#define ANSIBEG "\033["
+#define ANSIEND "m"
+
+#define ANSIRST ANSIBEG "0" ANSIEND
+
+#define ATNRM "0;"
+#define ATBLD "1;"
+#define ATDIM "2;"
+#define ATULN "3;"
+#define ATBNK "5;"
+#define ATREV "7;"
+#define ATHID "8;"
+
+#define FGBLK "30;"
+#define FGRED "31;"
+#define FGGRN "32;"
+#define FGYEL "33;"
+#define FGBLU "34;"
+#define FGMAG "35;"
+#define FGCYN "36;"
+#define FGWHT "37;"
+
+#define BGBLK "40"
+#define BGRED "41"
+#define BGGRN "42"
+#define BGYEL "43"
+#define BGBLU "44"
+#define BGMAG "45"
+#define BGCYN "46"
+#define BGWHT "47"
+
+enum qes_log_level {
+ /* The idea is that the user can add values inbetween these, if they need
+ * to. a la Python's logging module. */
+ QES_LOG_DEBUG = 0,
+ QES_LOG_INFO = 10,
+ QES_LOG_WARNING = 20,
+ QES_LOG_ERROR = 30,
+ QES_LOG_FATAL = 40,
+};
+
+typedef enum qes_log_level QesLogLevel;
+
+struct qes_log_entry {
+ char *message;
+ enum qes_log_level level;
+};
+
+typedef struct qes_log_entry QesLogEntry;
+struct qes_log_destination {
+ FILE *stream;
+ enum qes_log_level level;
+ char *(*formatter)(struct qes_log_entry *entry);
+};
+typedef struct qes_log_destination QesLogDestination;
+
+struct qes_logger {
+ struct qes_log_destination *destinations;
+ size_t n_destinations;
+ enum qes_log_level level;
+ char *name;
+ int lock;
+};
+typedef struct qes_logger QesLogger;
+
+
+struct qes_logger *qes_logger_create(void);
+int qes_logger_init(struct qes_logger *logger, const char *name,
+ enum qes_log_level level);
+int qes_logger_add_destination_formatted(struct qes_logger *logger,
+ FILE *stream,
+ enum qes_log_level level,
+ char *(*formatter)(struct qes_log_entry *entry));
+#define qes_logger_add_destination(log, stream, level) \
+ qes_logger_add_destination_formatted(log, stream, level, \
+ &qes_log_formatter_plain)
+void _qes_logger_destroy(struct qes_logger *logger);
+#define qes_logger_destroy(l) ({ _qes_logger_destroy(l); l = NULL; })
+
+
+struct qes_log_entry *qes_log_entry_create(void);
+int qes_log_entry_init(struct qes_log_entry *entry, enum qes_log_level level,
+ const char *message);
+void qes_log_entry_clear(struct qes_log_entry *entry);
+
+char *qes_log_formatter_plain(struct qes_log_entry *entry);
+char *qes_log_formatter_pretty(struct qes_log_entry *entry);
+
+int qes_log_entry_format(struct qes_log_entry *entry, enum qes_log_level level,
+ const char *format, ...);
+int qes_log_entry_format_va(struct qes_log_entry *entry,
+ enum qes_log_level level, const char *format,
+ va_list args);
+int qes_logger_write_entry(struct qes_logger *logger,
+ struct qes_log_entry *entry);
+void _qes_log_entry_destroy(struct qes_log_entry *log_entry);
+#define qes_log_entry_destroy(l) ({ _qes_log_entry_destroy(l); l = NULL; })
+
+
+int qes_log_message(struct qes_logger *logger, enum qes_log_level level,
+ const char *message);
+#ifndef NDEBUG
+#define qes_log_message_debug(log, msg) qes_log_message(log, QES_LOG_DEBUG, msg)
+#else
+#define qes_log_message_debug(log, msg)
+#endif
+#define qes_log_message_info(log, msg) qes_log_message(log, QES_LOG_INFO, msg)
+#define qes_log_message_warning(log, msg) qes_log_message(log, QES_LOG_WARNING, msg)
+#define qes_log_message_error(log, msg) qes_log_message(log, QES_LOG_ERROR, msg)
+#define qes_log_message_fatal(log, msg) qes_log_message(log, QES_LOG_FATAL, msg)
+
+
+int qes_log_format(struct qes_logger *logger, enum qes_log_level level,
+ const char *format, ...);
+#ifndef NDEBUG
+#define qes_log_format_debug(log, fmt, ...) \
+ qes_log_format(log, QES_LOG_DEBUG, fmt, __VA_ARGS__)
+#else
+#define qes_log_format_debug(log, fmt, ...)
+#endif
+#define qes_log_format_info(log, fmt, ...) \
+ qes_log_format(log, QES_LOG_INFO, fmt, __VA_ARGS__)
+#define qes_log_format_warning(log, fmt, ...) \
+ qes_log_format(log, QES_LOG_WARNING, fmt, __VA_ARGS__)
+#define qes_log_format_error(log, fmt, ...) \
+ qes_log_format(log, QES_LOG_ERROR, fmt, __VA_ARGS__)
+#define qes_log_format_fatal(log, fmt, ...) \
+ qes_log_format(log, QES_LOG_FATAL, fmt, __VA_ARGS__)
+
+
+#endif /* QES_LOG_H */
diff --git a/src/libqes/src/qes_match.c b/src/libqes/src/qes_match.c
new file mode 100644
index 0000000..1599b1a
--- /dev/null
+++ b/src/libqes/src/qes_match.c
@@ -0,0 +1,83 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_match.c
+ *
+ * Description: Sequence matching and finding functions used in
+ * bioinformatic tasks
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_match.h"
+
+
+inline int_fast32_t
+qes_match_hamming (const char *seq1, const char *seq2, size_t len)
+{
+ int_fast32_t mismatches = 0;
+ size_t iii = 0;
+
+ /* Error out on bad arguments */
+ if (seq1 == NULL || seq2 == NULL) {
+ return -1;
+ }
+ /* If we've been given a length of 0, we make it up ourselves */
+ if (len == 0) {
+ size_t len2 = strlen(seq2);
+ len = strlen(seq1);
+ /* Max of len & len2 */
+ if (len > len2) {
+ len = len2;
+ }
+ }
+ /* Count mismatches. See comment on analagous loop in qes_match_hamming_max
+ * for an explanation. */
+ while(iii < len) {
+ if (seq2[iii] != seq1[iii]) {
+ mismatches++;
+ }
+ iii++;
+ }
+ return mismatches;
+}
+
+
+inline int_fast32_t
+qes_match_hamming_max(const char *seq1, const char *seq2, size_t len,
+ int_fast32_t max)
+{
+ int_fast32_t mismatches = 0;
+ size_t iii = 0;
+
+ /* Error out on bad arguments */
+ if (seq1 == NULL || seq2 == NULL || max < 0) {
+ return -1;
+ }
+ /* If we've been given a lenght of 0, we make it up ourselves */
+ if (len == 0) {
+ size_t len2 = strlen(seq2);
+ len = strlen(seq1);
+ /* Max of len & len2 */
+ if (len > len2) {
+ len = len2;
+ }
+ }
+ /* We obediently go until ``len``, assuming whoever gave us ``len`` knew
+ WTF they were doing. This makes things a bit faster, since these
+ functions are expected to be very much inner-loop. */
+ while(iii < len) {
+ /* Find mismatch count */
+ if (seq2[iii] != seq1[iii]) {
+ mismatches++;
+ }
+ iii++;
+ if (mismatches > max) {
+ /* Bail out if we're over max, always cap at max + 1 */
+ return max + 1;
+ }
+ }
+ return mismatches;
+}
diff --git a/src/libqes/src/qes_match.h b/src/libqes/src/qes_match.h
new file mode 100644
index 0000000..31135a4
--- /dev/null
+++ b/src/libqes/src/qes_match.h
@@ -0,0 +1,50 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_match.h
+ *
+ * Description: Sequence matching and finding functions used in
+ * bioinformatic tasks
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_MATCH_H
+#define QES_MATCH_H
+
+#include <qes_util.h>
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_match_hamming
+Paramters: const char *seq1, *seq2: Two strings to compare.
+ size_t len: Compare ``len`` chars. If 0, guess length with
+ strlen (may be unsafe).
+Description: Find the hamming distance between two strings. The strings are
+ matched until the length of the smallest string.
+Returns: The hamming distance between ``seq1`` and ``seq2``, or -1 on
+ error.
+ *===========================================================================*/
+extern int_fast32_t qes_match_hamming(const char *seq1, const char *seq2, size_t len);
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_match_hamming_max
+Paramters: const char *seq1, *seq2: Two strings to compare.
+ size_t len: Compare ``len`` chars. If 0, guess length with
+ strlen (may be unsafe).
+ int_fast32_t max: Stop counting at ``max``, return ``max + 1``.
+Description: Find the hamming distance between two strings. The strings are
+ matched until the length of the smallest string, or ``len``
+ charachers, or until the maximum hamming distance (``max``) is
+ reached.
+Returns: The hamming distance between ``seq1`` and ``seq2``, or
+ ``max + 1`` if the hamming distance exceeds ``max``, or -1 on
+ error.
+ *===========================================================================*/
+extern int_fast32_t qes_match_hamming_max(const char *seq1, const char *seq2, size_t len,
+ int_fast32_t max);
+
+#endif /* QES_MATCH_H */
diff --git a/src/libqes/src/qes_seq.c b/src/libqes/src/qes_seq.c
new file mode 100644
index 0000000..9384fa8
--- /dev/null
+++ b/src/libqes/src/qes_seq.c
@@ -0,0 +1,157 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_seq.c
+ *
+ * Description: Sequence structures
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_seq.h"
+
+
+struct qes_seq *
+qes_seq_create (void)
+{
+ struct qes_seq *seq = qes_malloc(sizeof(*seq));
+
+ qes_str_init(&seq->name, __INIT_LINE_LEN);
+ qes_str_init(&seq->comment, __INIT_LINE_LEN);
+ qes_str_init(&seq->seq, __INIT_LINE_LEN);
+ qes_str_init(&seq->qual, __INIT_LINE_LEN);
+ return seq;
+}
+
+struct qes_seq *
+qes_seq_create_no_qual (void)
+{
+ struct qes_seq *seq = qes_malloc(sizeof(*seq));
+
+ qes_str_init(&seq->name, __INIT_LINE_LEN);
+ qes_str_init(&seq->comment, __INIT_LINE_LEN);
+ qes_str_init(&seq->seq, __INIT_LINE_LEN);
+ seq->qual.capacity = 0;
+ seq->qual.len = 0;
+ seq->qual.str = NULL;
+ return seq;
+}
+
+struct qes_seq *
+qes_seq_create_no_qual_or_comment (void)
+{
+ struct qes_seq *seq = qes_malloc(sizeof(*seq));
+ qes_str_init(&seq->name, __INIT_LINE_LEN);
+ qes_str_init(&seq->seq, __INIT_LINE_LEN);
+ seq->qual.capacity = 0;
+ seq->qual.len = 0;
+ seq->qual.str = NULL;
+ seq->comment.capacity = 0;
+ seq->comment.len = 0;
+ seq->comment.str = NULL;
+ return seq;
+}
+
+
+inline int
+qes_seq_fill_name (struct qes_seq *seqobj, const char *name, size_t len)
+{
+ if (seqobj == NULL || name == NULL || len < 1) {
+ return 1;
+ }
+ qes_str_fill_charptr(&seqobj->name, name, len);
+ return 0;
+}
+
+inline int
+qes_seq_fill_comment (struct qes_seq *seqobj, const char *comment, size_t len)
+{
+ if (seqobj == NULL || comment == NULL || len < 1) {
+ return 1;
+ }
+ qes_str_fill_charptr(&seqobj->comment, comment, len);
+ return 0;
+}
+
+inline int
+qes_seq_fill_seq (struct qes_seq *seqobj, const char *seq, size_t len)
+{
+ if (seqobj == NULL || seq == NULL || len < 1) {
+ return 1;
+ }
+ qes_str_fill_charptr(&seqobj->seq, seq, len);
+ return 0;
+}
+
+inline int
+qes_seq_fill_qual (struct qes_seq *seqobj, const char *qual, size_t len)
+{
+ if (seqobj == NULL || qual == NULL || len < 1) {
+ return 1;
+ }
+ qes_str_fill_charptr(&seqobj->qual, qual, len);
+ return 0;
+}
+
+inline int
+qes_seq_fill_header (struct qes_seq *seqobj, char *header, size_t len)
+{
+ char *tmp = NULL;
+ size_t startfrom = 0;
+
+ if (seqobj == NULL || header == NULL) {
+ return 1;
+ }
+ if (len < 1) {
+ len = strlen(header);
+ }
+ while (isspace(header[len-1])) {
+ header[--len] = '\0';
+ }
+ tmp = memchr(header, ' ', len);
+ startfrom = header[0] == '@' || header[0] == '>' ? 1 : 0;
+ if (tmp != NULL) {
+ qes_str_fill_charptr(&seqobj->name, header + startfrom,
+ tmp - header - startfrom);
+ qes_str_fill_charptr(&seqobj->comment, tmp + 1, 0);
+ } else {
+ qes_str_fill_charptr(&seqobj->name, header + startfrom, len - startfrom);
+ qes_str_nullify(&seqobj->comment);
+ }
+ return 0;
+}
+
+inline int
+qes_seq_fill(struct qes_seq *seqobj, const char *name, const char *comment,
+ const char *seq, const char *qual)
+{
+ if (!qes_seq_ok(seqobj) || name == NULL || comment == NULL || seq == NULL \
+ || qual == NULL) {
+ return 1;
+ }
+ if (qes_seq_fill_name(seqobj, name, strlen(name)) != 0) return 1;
+ if (qes_seq_fill_comment(seqobj, comment, strlen(comment)) != 0) return 1;
+ if (qes_seq_fill_seq(seqobj, seq, strlen(seq)) != 0) return 1;
+ if (qes_seq_fill_qual(seqobj, qual, strlen(qual)) != 0) return 1;
+ return 0;
+}
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_destroy
+Paramters: struct qes_seq *: seq to destroy.
+Description: Deallocate and set to NULL a struct qes_seq on the heap.
+Returns: void.
+ *===========================================================================*/
+void
+qes_seq_destroy_ (struct qes_seq *seq)
+{
+ if (seq != NULL) {
+ qes_str_destroy_cp(&seq->name);
+ qes_str_destroy_cp(&seq->comment);
+ qes_str_destroy_cp(&seq->seq);
+ qes_str_destroy_cp(&seq->qual);
+ qes_free(seq);
+ }
+}
diff --git a/src/libqes/src/qes_seq.h b/src/libqes/src/qes_seq.h
new file mode 100644
index 0000000..fb2c65a
--- /dev/null
+++ b/src/libqes/src/qes_seq.h
@@ -0,0 +1,187 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_seq.h
+ *
+ * Description: Sequence structures
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_SEQ_H
+#define QES_SEQ_H
+
+#include <qes_util.h>
+#include <qes_str.h>
+
+
+/*---------------------------------------------------------------------------
+ | qes_seq module -- data structures to hold NGS sequences |
+ ---------------------------------------------------------------------------*/
+
+/* TYPE DEFINITIONS */
+struct qes_seq {
+ struct qes_str name;
+ struct qes_str comment;
+ struct qes_str seq;
+ struct qes_str qual;
+};
+
+/* PROTOTYPES */
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_create
+Paramters: void
+Description: Create a ``struct qes_seq`` object on the heap, creating and
+ initialising all members. qes_seq_create_no_X functions do not
+ create or initialise the members in their names.
+Returns: struct qes_seq *: A non-null memory address on success, otherwise NULL.
+ *===========================================================================*/
+struct qes_seq *qes_seq_create (void);
+struct qes_seq *qes_seq_create_no_qual (void);
+struct qes_seq *qes_seq_create_no_qual_or_comment (void);
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_ok
+Paramters: struct qes_seq *: seq to check
+Description: Check if ``seq`` is a usable struct qes_seq struct. qes_seq_ok_no-X
+ functions permit the member(s) in their names to be unusable.
+Returns: 1 if usable, 0 otherwise.
+ *===========================================================================*/
+static inline int
+qes_seq_ok (const struct qes_seq *seq)
+{
+ return \
+ seq != NULL && \
+ qes_str_ok(&seq->name) && \
+ qes_str_ok(&seq->comment) && \
+ qes_str_ok(&seq->seq) && \
+ qes_str_ok(&seq->qual);
+}
+
+static inline int
+qes_seq_ok_no_comment (const struct qes_seq *seq)
+{
+ return \
+ seq != NULL && \
+ qes_str_ok(&seq->name) && \
+ qes_str_ok(&seq->seq) && \
+ qes_str_ok(&seq->qual);
+}
+
+static inline int
+qes_seq_ok_no_qual (const struct qes_seq *seq)
+{
+ return \
+ seq != NULL && \
+ qes_str_ok(&seq->name) && \
+ qes_str_ok(&seq->comment) && \
+ qes_str_ok(&seq->seq);
+}
+
+static inline int
+qes_seq_ok_no_comment_or_qual (const struct qes_seq *seq)
+{
+ return \
+ seq != NULL && \
+ qes_str_ok(&seq->name) && \
+ qes_str_ok(&seq->seq);
+}
+
+static inline int
+qes_seq_has_comment (const struct qes_seq *seq)
+{
+ return qes_seq_ok(seq) && seq->comment.len > 0;
+}
+
+static inline int
+qes_seq_has_qual (const struct qes_seq *seq)
+{
+ return qes_seq_ok(seq) && seq->qual.len > 0;
+}
+
+static inline int
+qes_seq_n_bytes (const struct qes_seq *seq)
+{
+ if (!qes_seq_ok(seq)) {
+ return -1;
+ }
+ /* Arragned per line in a fastq */
+ return 1 + seq->name.len + \
+ (qes_seq_has_comment(seq) ? 1 + seq->comment.len : 0) + 1 + \
+ seq->seq.len + 1 +\
+ qes_seq_has_qual(seq) ? 2 + seq->qual.len + 1 : 0;
+}
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_fill_header
+Paramters: struct qes_seq *seqobj: Seq object that will receive the header.
+Description: Fills the name and comment members of a ``struct qes_seq`` from the
+ header line of a fasta/fastq file.
+Returns: int: 1 on success, otherwise 0 for failure.
+ *===========================================================================*/
+extern int qes_seq_fill_header(struct qes_seq *seqobj, char *header, size_t len);
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_fill_X
+Paramters: These functions take a ``struct qes_seq``, a char array and
+ the length of the char array as a size_t.
+Description: Fill a struct qes_seq's name, comment, seq or qual member from
+ a char array. If a non-zero value is given to ``len``, it is
+ assumed to be the length of the string, otherwise the length of
+ the string is calculated using strlen.
+Returns: int: 1 on success, 0 on failure.
+ *===========================================================================*/
+extern int qes_seq_fill_name(struct qes_seq *seqobj, const char *name,
+ size_t len);
+extern int qes_seq_fill_comment(struct qes_seq *seqobj, const char *comment,
+ size_t len);
+extern int qes_seq_fill_seq(struct qes_seq *seqobj, const char *seq,
+ size_t len);
+extern int qes_seq_fill_qual(struct qes_seq *seqobj, const char *qual,
+ size_t len);
+extern int qes_seq_fill(struct qes_seq *seqobj, const char *name,
+ const char *comment, const char *seq, const char *qual);
+
+#if 0
+/*=== FUNCTION ============================================================*
+Name: qes_seq_print
+Paramters: const struct qes_seq *: seq to print
+ qes_seqfile_format_t: file format to print in.
+ FILE *: open file stream to print to.
+Description: Print ``seq`` in formatted per ``format`` to ``stream``.
+Returns: int: 1 on success, 0 on failure.
+ *===========================================================================*/
+extern int qes_seq_print (const struct qes_seq *seq,
+ enum qes_seqfile_format fmt, FILE *stream);
+#endif
+
+/*=== FUNCTION ============================================================*
+Name: qes_seq_destroy
+Paramters: struct qes_seq *: seq to destroy.
+Description: Deallocate and set to NULL a struct qes_seq on the heap.
+Returns: void.
+ *===========================================================================*/
+void qes_seq_destroy_(struct qes_seq *seq);
+#define qes_seq_destroy(seq) do { \
+ qes_seq_destroy_(seq); \
+ seq = NULL; \
+ } while(0)
+
+static inline int
+qes_seq_copy(struct qes_seq *dest, const struct qes_seq *src)
+{
+ if (dest == src || !qes_seq_ok(dest) || !qes_seq_ok(src)) return 1;
+
+ if (qes_str_copy(&dest->name, &src->name) != 0) return 1;
+ if (qes_str_copy(&dest->comment, &src->comment) != 0) return 1;
+ if (qes_str_copy(&dest->seq, &src->seq) != 0) return 1;
+ if (qes_str_copy(&dest->qual, &src->qual) != 0) return 1;
+ return 0;
+}
+
+#endif /* QES_SEQ_H */
diff --git a/src/libqes/src/qes_seqfile.c b/src/libqes/src/qes_seqfile.c
new file mode 100644
index 0000000..b876252
--- /dev/null
+++ b/src/libqes/src/qes_seqfile.c
@@ -0,0 +1,319 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_seqfile.c
+ *
+ * Description: qes_seqfile -- read sequences in FASTA or FASTQ format.
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_seqfile.h"
+
+
+static inline ssize_t
+read_fastq_seqfile(struct qes_seqfile *seqfile, struct qes_seq *seq)
+{
+ /* Convenience macro, this happens a lot */
+#define CHECK_AND_TRIM(subrec) if (len < 1) { \
+ goto error; \
+ } else { \
+ subrec.str[--len] = '\0'; \
+ subrec.len = len; \
+ }
+ ssize_t len = 0;
+ int next = '\0';
+ int errcode = -1;
+
+ /* Fast-forward past the delimiter '@', ensuring it exists */
+ next = qes_file_getc(seqfile->qf);
+ if (next == EOF) {
+ return EOF;
+ } else if (next != FASTQ_DELIM) {
+ /* This ain't a fastq! WTF! */
+ errcode = -3;
+ goto error;
+ }
+ len = qes_file_readline_str(seqfile->qf, &seqfile->scratch);
+ if (len < 1) {
+ /* Weird truncated file */
+ errcode = -3;
+ goto error;
+ }
+ qes_seq_fill_header(seq, seqfile->scratch.str, seqfile->scratch.len);
+ /* Fill the actual sequence directly */
+ len = qes_file_readline_str(seqfile->qf, &seq->seq);
+ errcode = -4;
+ CHECK_AND_TRIM(seq->seq)
+ /* read the qual header, but don't store it. */
+ errcode = -5;
+ next = qes_file_getc(seqfile->qf);
+ if (next != FASTQ_QUAL_DELIM) {
+ goto error;
+ }
+ while ((next = qes_file_getc(seqfile->qf)) != '\n') {
+ if (next == EOF) {
+ goto error;
+ }
+ }
+ if (next != '\n') goto error;
+ /* Fill the qual score string directly */
+ len = qes_file_readline_str(seqfile->qf, &seq->qual);
+ errcode = -6;
+ CHECK_AND_TRIM(seq->qual)
+ if ((size_t)len != seq->seq.len) {
+ /* Error out on different len qual/seq entries */
+ errcode = -7;
+ goto error;
+ }
+ /* return seq/qual len */
+ seqfile->n_records++;
+ return seq->seq.len;
+error:
+ qes_str_nullify(&seq->name);
+ qes_str_nullify(&seq->comment);
+ qes_str_nullify(&seq->seq);
+ qes_str_nullify(&seq->qual);
+ return errcode;
+#undef CHECK_AND_TRIM
+}
+
+static inline ssize_t
+read_fasta_seqfile(struct qes_seqfile *seqfile, struct qes_seq *seq)
+{
+ /* Convenience macro, this happens a lot */
+#define CHECK_AND_TRIM(subrec) if (len < 1) { \
+ goto error; \
+ } else { \
+ subrec.str[--len] = '\0'; \
+ subrec.len = len; \
+ }
+ ssize_t len = 0;
+ int next = '\0';
+
+ /* This bit is basically a copy-paste from above */
+ /* Fast-forward past the delimiter '>', ensuring it exists */
+ next = qes_file_getc(seqfile->qf);
+ if (next == EOF) {
+ return EOF;
+ } else if (next != FASTA_DELIM) {
+ /* This ain't a fasta! WTF! */
+ goto error;
+ }
+ len = qes_file_readline_str(seqfile->qf, &seqfile->scratch);
+ if (len < 1) {
+ goto error;
+ }
+ qes_seq_fill_header(seq, seqfile->scratch.str, seqfile->scratch.len);
+ /* we need to nullify seq, as we rely on seq.len being 0 as we enter this
+ * while loop */
+ qes_str_nullify(&seq->seq);
+ /* While the next char is not a '>', i.e. until next header line */
+ while ((next = qes_file_peek(seqfile->qf)) != EOF && next != FASTA_DELIM) {
+ len = qes_file_readline(seqfile->qf, seq->seq.str + seq->seq.len,
+ seq->seq.capacity - seq->seq.len - 1);
+ if (len < 0) {
+ goto error;
+ }
+ seq->seq.len += len - 1;
+ seq->seq.str[seq->seq.len] = '\0';
+ if (seq->seq.capacity - 1 <= seq->seq.len) {
+ seq->seq.capacity = qes_roundupz(seq->seq.capacity);
+ seq->seq.str = qes_realloc(seq->seq.str,
+ sizeof(*seq->seq.str) * seq->seq.capacity);
+ if (seq->seq.str == NULL) {
+ goto error;
+ }
+ }
+ }
+ seq->seq.str[seq->seq.len] = '\0';
+ /* return seq len */
+ seqfile->n_records++;
+ qes_str_nullify(&seq->qual);
+ return seq->seq.len;
+error:
+ qes_str_nullify(&seq->name);
+ qes_str_nullify(&seq->comment);
+ qes_str_nullify(&seq->seq);
+ qes_str_nullify(&seq->qual);
+ return -2;
+#undef CHECK_AND_TRIM
+}
+
+ssize_t
+qes_seqfile_read (struct qes_seqfile *seqfile, struct qes_seq *seq)
+{
+ if (!qes_seqfile_ok(seqfile) || !qes_seq_ok(seq)) {
+ return -2;
+ }
+ if (seqfile->qf->eof) {
+ return EOF;
+ }
+ if (seqfile->format == FASTQ_FMT) {
+ return read_fastq_seqfile(seqfile, seq);
+ } else if (seqfile->format == FASTA_FMT) {
+ return read_fasta_seqfile(seqfile, seq);
+ }
+ /* If we reach here, bail out with an error */
+ qes_str_nullify(&seq->name);
+ qes_str_nullify(&seq->comment);
+ qes_str_nullify(&seq->seq);
+ qes_str_nullify(&seq->qual);
+ return -2;
+}
+
+struct qes_seqfile *
+qes_seqfile_create (const char *path, const char *mode)
+{
+ struct qes_seqfile *sf = NULL;
+ if (path == NULL || mode == NULL) return NULL;
+ sf = qes_calloc(1, sizeof(*sf));
+ sf->qf = qes_file_open(path, mode);
+ if (sf->qf == NULL) {
+ qes_free(sf->qf);
+ qes_free(sf);
+ return NULL;
+ }
+ qes_str_init(&sf->scratch, __INIT_LINE_LEN);
+ sf->n_records = 0;
+ qes_seqfile_guess_format(sf);
+ return sf;
+}
+
+enum qes_seqfile_format
+qes_seqfile_guess_format (struct qes_seqfile *seqfile)
+{
+ int first_char = '\0';
+ if (!qes_seqfile_ok(seqfile)) return UNKNOWN_FMT;
+ if (!qes_file_readable(seqfile->qf)) return UNKNOWN_FMT;
+ first_char = qes_file_peek(seqfile->qf);
+ switch (first_char) {
+ case FASTQ_DELIM:
+ seqfile->format = FASTQ_FMT;
+ return FASTQ_FMT;
+ break;
+ case FASTA_DELIM:
+ seqfile->format = FASTA_FMT;
+ return FASTA_FMT;
+ break;
+ default:
+ seqfile->format = UNKNOWN_FMT;
+ return UNKNOWN_FMT;
+ }
+}
+
+void
+qes_seqfile_set_format (struct qes_seqfile *seqfile,
+ enum qes_seqfile_format format)
+{
+ if (!qes_seqfile_ok(seqfile)) return;
+ seqfile->format = format;
+}
+
+void
+qes_seqfile_destroy_(struct qes_seqfile *seqfile)
+{
+ if (seqfile != NULL) {
+ qes_file_close(seqfile->qf);
+ qes_str_destroy_cp(&seqfile->scratch);
+ qes_free(seqfile);
+ }
+}
+
+size_t
+qes_seqfile_format_seq(const struct qes_seq *seq, enum qes_seqfile_format fmt,
+ char *buffer, size_t maxlen)
+{
+ size_t len = 0;
+ if (buffer == NULL || maxlen < 1) {
+ return 0;
+ }
+ switch (fmt) {
+ case FASTQ_FMT:
+ if (!qes_seq_ok(seq)) {
+ buffer[0] = '\0';
+ return 0;
+ }
+ len = snprintf(buffer, maxlen, "%c%s %s\n%s\n%c\n%s\n",
+ FASTQ_DELIM, seq->name.str, seq->comment.str,
+ seq->seq.str,
+ FASTQ_QUAL_DELIM,
+ seq->qual.str);
+ return len;
+ break;
+ case FASTA_FMT:
+ if (!qes_seq_ok_no_qual(seq)) {
+ buffer[0] = '\0';
+ return 0;
+ }
+ len = snprintf(buffer, maxlen, "%c%s %s\n%s\n",
+ FASTA_DELIM, seq->name.str, seq->comment.str,
+ seq->seq.str);
+ return len;
+ break;
+ case UNKNOWN_FMT:
+ default:
+ return 0;
+ }
+}
+
+
+ssize_t
+qes_seqfile_write (struct qes_seqfile *seqfile, struct qes_seq *seq)
+{
+#define sf_putc_check(c) ret = QES_ZFPUTC(seqfile->qf->fp, c); \
+ if (ret != c) {return -2;} \
+ else {res_len += 1;} \
+ ret = 0
+#define sf_puts_check(s) ret = QES_ZFPUTS(seqfile->qf->fp, s.str); \
+ if (ret < 0) {return -2;} \
+ else {res_len += s.len;} \
+ ret = 0
+
+ int ret = 0;
+ ssize_t res_len = 0;
+
+ if (!qes_seqfile_ok(seqfile) || !qes_seq_ok(seq)) {
+ return -2;
+ }
+ switch (seqfile->format) {
+ case FASTA_FMT:
+ sf_putc_check(FASTA_DELIM);
+ sf_puts_check(seq->name);
+ if (qes_seq_has_comment(seq)) {
+ sf_putc_check(' ');
+ sf_puts_check(seq->comment);
+ }
+ sf_putc_check('\n');
+ sf_puts_check(seq->seq);
+ sf_putc_check('\n');
+ break;
+ case FASTQ_FMT:
+ sf_putc_check(FASTQ_DELIM);
+ sf_puts_check(seq->name);
+ if (qes_seq_has_comment(seq)) {
+ sf_putc_check(' ');
+ sf_puts_check(seq->comment);
+ }
+ sf_putc_check('\n');
+ sf_puts_check(seq->seq);
+ sf_putc_check('\n');
+ if (qes_seq_has_qual(seq)) {
+ sf_putc_check('+');
+ sf_putc_check('\n');
+ sf_puts_check(seq->qual);
+ sf_putc_check('\n');
+
+ }
+ break;
+ case UNKNOWN_FMT:
+ default:
+ return -2;
+ break;
+ }
+ return res_len;
+#undef sf_putc_check
+#undef sf_puts_check
+}
diff --git a/src/libqes/src/qes_seqfile.h b/src/libqes/src/qes_seqfile.h
new file mode 100644
index 0000000..eefccc6
--- /dev/null
+++ b/src/libqes/src/qes_seqfile.h
@@ -0,0 +1,224 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_seqfile.h
+ *
+ * Description: qes_seqfile -- read sequences in FASTA or FASTQ format.
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_SEQFILE_H
+#define QES_SEQFILE_H
+
+#include <qes_util.h>
+#include <qes_seq.h>
+#include <qes_file.h>
+
+
+/*--------------------------------------------------------------------------
+ | Seqfile -- seamless reading & writing of FASTA & FASTQ |
+ ---------------------------------------------------------------------------*/
+
+#define FASTA_DELIM '>'
+#define FASTQ_DELIM '@'
+#define FASTQ_QUAL_DELIM '+'
+
+enum qes_seqfile_format {
+ UNKNOWN_FMT = 0,
+ FASTA_FMT = 1,
+ FASTQ_FMT = 2,
+};
+
+struct qes_seqfile {
+ struct qes_file *qf;
+ size_t n_records;
+ enum qes_seqfile_format format;
+ /* A buffer to store misc shit in while reading.
+ One per file to keep it re-entrant */
+ struct qes_str scratch;
+};
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_seqfile_create
+Paramters: const char *path: Path to open.
+ const char *mode: Mode to pass to the fopen equivalent used.
+Description: Allocates structures, initialises values and opens the internal
+ file handle.
+Returns: A fully usable ``struct qes_seqfile *`` or NULL.
+ *===========================================================================*/
+struct qes_seqfile *qes_seqfile_create (const char *path, const char *mode);
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_seqfile_ok
+Paramters: const struct qes_seqfile *file: File reference to check.
+Description: Check a file referenece ``file``, ensuring that it may be
+ dereferenced and used. This checks if a buffer has been
+ allocated and buffer pointers set appropriately IFF the file is
+ opened for reading. No guarantees are given about being able to
+ read from the file.
+Returns: An int evaluating to true if ``file`` is OK, otherwise false.
+ *===========================================================================*/
+static inline int
+qes_seqfile_ok(const struct qes_seqfile *file)
+{
+ return (file != NULL && qes_file_ok(file->qf));
+}
+
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_seqfile_guess_format
+Paramters: struct qes_seqfile *file: File whose format we guess.
+Description: Guess, using qes_file_peek, the format of ``file``. This only inspects
+ the first character, so it will be confused if the first
+ character of the file is incorrect. Only use this at the start
+ of a file (this is checked).
+Returns: The file's format as a enum qes_seqfile_format, or UNKNOWN_FMT if the
+ file is not readable, or not a FASTA/FASTQ file.
+ *===========================================================================*/
+enum qes_seqfile_format qes_seqfile_guess_format(struct qes_seqfile *file);
+
+void qes_seqfile_set_format (struct qes_seqfile *file,
+ enum qes_seqfile_format format);
+
+ssize_t qes_seqfile_read (struct qes_seqfile *file, struct qes_seq *seq);
+
+ssize_t qes_seqfile_write (struct qes_seqfile *file, struct qes_seq *seq);
+
+size_t qes_seqfile_format_seq(const struct qes_seq *seq, enum qes_seqfile_format fmt,
+ char *buffer, size_t maxlen);
+
+void qes_seqfile_destroy_(struct qes_seqfile *seqfile);
+#define qes_seqfile_destroy(seqfile) do { \
+ qes_seqfile_destroy_(seqfile); \
+ seqfile = NULL; \
+ } while(0)
+
+#ifdef OPENMP_FOUND
+#define QES_SEQFILE_ITER_PARALLEL_SINGLE_BEGIN(fle, sq, ln, opts) \
+ _Pragma(STRINGIFY(omp parallel shared(fle) opts default(none))) \
+ { \
+ struct qes_seq *sq = qes_seq_create(); \
+ ssize_t ln = 0; \
+ while(1) { \
+ _Pragma(STRINGIFY(omp critical)) \
+ { \
+ ln = qes_seqfile_read(fle, sq); \
+ } \
+ if (ln < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_PARALLEL_SINGLE_END(sq) \
+ } \
+ qes_seq_destroy(sq); \
+ }
+
+#define QES_SEQFILE_ITER_PARALLEL_PAIRED_BEGIN(fle1, fle2, sq1, sq2, ln1, ln2, opts)\
+ _Pragma(STRINGIFY(omp parallel shared(fle1, fle2) opts default(none))) \
+ { \
+ struct qes_seq *sq1 = qes_seq_create(); \
+ struct qes_seq *sq2 = qes_seq_create(); \
+ ssize_t ln1 = 0; \
+ ssize_t ln2 = 0; \
+ while(1) { \
+ _Pragma(STRINGIFY(omp critical)) \
+ { \
+ ln1 = qes_seqfile_read(fle1, sq1); \
+ ln2 = qes_seqfile_read(fle2, sq2); \
+ } \
+ if (ln1 < 0 || ln2 < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_PARALLEL_PAIRED_END(sq1, sq2) \
+ } \
+ qes_seq_destroy(sq1); \
+ qes_seq_destroy(sq2); \
+ }
+
+#define QES_SEQFILE_ITER_PARALLEL_INTERLEAVED_BEGIN(fle, sq1, sq2, ln1, ln2, opts)\
+ _Pragma(STRINGIFY(omp parallel shared(fle) opts default(none))) \
+ { \
+ struct qes_seq *sq1 = qes_seq_create(); \
+ struct qes_seq *sq2 = qes_seq_create(); \
+ ssize_t ln1 = 0; \
+ ssize_t ln2 = 0; \
+ while(1) { \
+ _Pragma(STRINGIFY(omp critical)) \
+ { \
+ ln1 = qes_seqfile_read(fle, sq1); \
+ ln2 = qes_seqfile_read(fle, sq2); \
+ } \
+ if (ln1 < 0 || ln2 < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_PARALLEL_INTERLEAVED_END(sq1, sq2) \
+ } \
+ qes_seq_destroy(sq1); \
+ qes_seq_destroy(sq2); \
+ }
+
+#endif /* OPENMP_FOUND */
+
+#define QES_SEQFILE_ITER_SINGLE_BEGIN(fle, sq, ln) \
+ { \
+ struct qes_seq *sq = qes_seq_create(); \
+ /* TODO MUSTFIX check for null sq */ \
+ ssize_t ln = 0; \
+ while(1) { \
+ ln = qes_seqfile_read(fle, sq); \
+ if (ln < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_SINGLE_END(sq) \
+ } \
+ qes_seq_destroy(sq); \
+ }
+
+#define QES_SEQFILE_ITER_PAIRED_BEGIN(fle1, fle2, sq1, sq2, ln1, ln2) \
+ { \
+ struct qes_seq *sq1 = qes_seq_create(); \
+ struct qes_seq *sq2 = qes_seq_create(); \
+ ssize_t ln1 = 0; \
+ ssize_t ln2 = 0; \
+ while(1) { \
+ ln1 = qes_seqfile_read(fle1, sq1); \
+ ln2 = qes_seqfile_read(fle2, sq2); \
+ if (ln1 < 0 || ln2 < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_PAIRED_END(sq1, sq2) \
+ } \
+ qes_seq_destroy(sq1); \
+ qes_seq_destroy(sq2); \
+ }
+
+#define QES_SEQFILE_ITER_INTERLEAVED_BEGIN(fle, sq1, sq2, ln1, ln2) \
+ { \
+ struct qes_seq *sq1 = qes_seq_create(); \
+ struct qes_seq *sq2 = qes_seq_create(); \
+ ssize_t ln1 = 0; \
+ ssize_t ln2 = 0; \
+ while(1) { \
+ ln1 = qes_seqfile_read(fle, sq1); \
+ ln2 = qes_seqfile_read(fle, sq2); \
+ if (ln1 < 0 || ln2 < 0) { \
+ break; \
+ }
+
+#define QES_SEQFILE_ITER_INTERLEAVED_END(sq1, sq2) \
+ } \
+ qes_seq_destroy(sq1); \
+ qes_seq_destroy(sq2); \
+ }
+
+#endif /* QES_SEQFILE_H */
diff --git a/src/libqes/src/qes_sequtil.c b/src/libqes/src/qes_sequtil.c
new file mode 100644
index 0000000..f8847d1
--- /dev/null
+++ b/src/libqes/src/qes_sequtil.c
@@ -0,0 +1,256 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_sequtil.c
+ *
+ * Description: Sequence utility functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_sequtil.h"
+
+
+/*
+ * === FUNCTION =============================================================
+ * Name: qes_sequtil_translate_codon
+ * Description: translate a codon to an amino acid.
+ * ============================================================================
+ */
+
+inline char
+qes_sequtil_translate_codon (const char *codon)
+{
+ if (codon == NULL || strnlen(codon, 4) != 3) {
+ return -1;
+ }
+ if (codon[0] == 'A') {
+ if (codon[1] == 'A') {
+ if (codon[2] == 'A') return 'K';
+ else if (codon[2] == 'C') return 'N';
+ else if (codon[2] == 'G') return 'K';
+ else if (codon[2] == 'T') return 'N';
+ else if (codon[2] == 'U') return 'N';
+ }
+ else if (codon[1] == 'C') {
+ if (codon[2] == 'A') return 'T';
+ else if (codon[2] == 'C') return 'T';
+ else if (codon[2] == 'G') return 'T';
+ else if (codon[2] == 'T') return 'T';
+ else if (codon[2] == 'U') return 'T';
+ }
+ else if (codon[1] == 'G') {
+ if (codon[2] == 'A') return 'R';
+ else if (codon[2] == 'C') return 'S';
+ else if (codon[2] == 'G') return 'R';
+ else if (codon[2] == 'T') return 'S';
+ else if (codon[2] == 'U') return 'S';
+ }
+ else if (codon[1] == 'T') {
+ if (codon[2] == 'A') return 'I';
+ else if (codon[2] == 'C') return 'I';
+ else if (codon[2] == 'G') return 'M';
+ else if (codon[2] == 'T') return 'I';
+ else if (codon[2] == 'U') return 'I';
+ }
+ else if (codon[1] == 'U') {
+ if (codon[2] == 'A') return 'I';
+ else if (codon[2] == 'C') return 'I';
+ else if (codon[2] == 'G') return 'M';
+ else if (codon[2] == 'T') return 'I';
+ else if (codon[2] == 'U') return 'I';
+ }
+ }
+ else if (codon[0] == 'C') {
+ if (codon[1] == 'A') {
+ if (codon[2] == 'A') return 'Q';
+ else if (codon[2] == 'C') return 'H';
+ else if (codon[2] == 'G') return 'Q';
+ else if (codon[2] == 'T') return 'H';
+ else if (codon[2] == 'U') return 'H';
+ }
+ else if (codon[1] == 'C') {
+ if (codon[2] == 'A') return 'P';
+ else if (codon[2] == 'C') return 'P';
+ else if (codon[2] == 'G') return 'P';
+ else if (codon[2] == 'T') return 'P';
+ else if (codon[2] == 'U') return 'P';
+ }
+ else if (codon[1] == 'G') {
+ if (codon[2] == 'A') return 'R';
+ else if (codon[2] == 'C') return 'R';
+ else if (codon[2] == 'G') return 'R';
+ else if (codon[2] == 'T') return 'R';
+ else if (codon[2] == 'U') return 'R';
+ }
+ else if (codon[1] == 'T') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'L';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'L';
+ else if (codon[2] == 'U') return 'L';
+ }
+ else if (codon[1] == 'U') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'L';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'L';
+ else if (codon[2] == 'U') return 'L';
+ }
+ }
+ else if (codon[0] == 'G') {
+ if (codon[1] == 'A') {
+ if (codon[2] == 'A') return 'E';
+ else if (codon[2] == 'C') return 'D';
+ else if (codon[2] == 'G') return 'E';
+ else if (codon[2] == 'T') return 'D';
+ else if (codon[2] == 'U') return 'D';
+ }
+ else if (codon[1] == 'C') {
+ if (codon[2] == 'A') return 'A';
+ else if (codon[2] == 'C') return 'A';
+ else if (codon[2] == 'G') return 'A';
+ else if (codon[2] == 'T') return 'A';
+ else if (codon[2] == 'U') return 'A';
+ }
+ else if (codon[1] == 'G') {
+ if (codon[2] == 'A') return 'G';
+ else if (codon[2] == 'C') return 'G';
+ else if (codon[2] == 'G') return 'G';
+ else if (codon[2] == 'T') return 'G';
+ else if (codon[2] == 'U') return 'G';
+ }
+ else if (codon[1] == 'T') {
+ if (codon[2] == 'A') return 'V';
+ else if (codon[2] == 'C') return 'V';
+ else if (codon[2] == 'G') return 'V';
+ else if (codon[2] == 'T') return 'V';
+ else if (codon[2] == 'U') return 'V';
+ }
+ else if (codon[1] == 'U') {
+ if (codon[2] == 'A') return 'V';
+ else if (codon[2] == 'C') return 'V';
+ else if (codon[2] == 'G') return 'V';
+ else if (codon[2] == 'T') return 'V';
+ else if (codon[2] == 'U') return 'V';
+ }
+ }
+ else if (codon[0] == 'T') {
+ if (codon[1] == 'A') {
+ if (codon[2] == 'A') return '*';
+ else if (codon[2] == 'C') return 'Y';
+ else if (codon[2] == 'G') return '*';
+ else if (codon[2] == 'T') return 'Y';
+ else if (codon[2] == 'U') return 'Y';
+ }
+ else if (codon[1] == 'C') {
+ if (codon[2] == 'A') return 'S';
+ else if (codon[2] == 'C') return 'S';
+ else if (codon[2] == 'G') return 'S';
+ else if (codon[2] == 'T') return 'S';
+ else if (codon[2] == 'U') return 'S';
+ }
+ else if (codon[1] == 'G') {
+ if (codon[2] == 'A') return '*';
+ else if (codon[2] == 'C') return 'C';
+ else if (codon[2] == 'G') return 'W';
+ else if (codon[2] == 'T') return 'C';
+ else if (codon[2] == 'U') return 'C';
+ }
+ else if (codon[1] == 'T') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'F';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'F';
+ else if (codon[2] == 'U') return 'F';
+ }
+ else if (codon[1] == 'U') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'F';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'F';
+ else if (codon[2] == 'U') return 'F';
+ }
+ }
+ else if (codon[0] == 'U') {
+ if (codon[1] == 'A') {
+ if (codon[2] == 'A') return '*';
+ else if (codon[2] == 'C') return 'Y';
+ else if (codon[2] == 'G') return '*';
+ else if (codon[2] == 'T') return 'Y';
+ else if (codon[2] == 'U') return 'Y';
+ }
+ else if (codon[1] == 'C') {
+ if (codon[2] == 'A') return 'S';
+ else if (codon[2] == 'C') return 'S';
+ else if (codon[2] == 'G') return 'S';
+ else if (codon[2] == 'T') return 'S';
+ else if (codon[2] == 'U') return 'S';
+ }
+ else if (codon[1] == 'G') {
+ if (codon[2] == 'A') return '*';
+ else if (codon[2] == 'C') return 'C';
+ else if (codon[2] == 'G') return 'W';
+ else if (codon[2] == 'T') return 'C';
+ else if (codon[2] == 'U') return 'C';
+ }
+ else if (codon[1] == 'T') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'F';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'F';
+ else if (codon[2] == 'U') return 'F';
+ }
+ else if (codon[1] == 'U') {
+ if (codon[2] == 'A') return 'L';
+ else if (codon[2] == 'C') return 'F';
+ else if (codon[2] == 'G') return 'L';
+ else if (codon[2] == 'T') return 'F';
+ else if (codon[2] == 'U') return 'F';
+ }
+ }
+ return 'X';
+}
+
+
+inline char *
+qes_sequtil_revcomp (const char *seq, size_t len)
+{
+ size_t seqlen = strlen(seq);
+ char *outseq = strdup(seq);
+ seqlen = seqlen < len ? seqlen : len - 1;
+
+ if (outseq[seqlen - 1] == '\n') {
+ outseq[seqlen - 1] = '\0';
+ seqlen--;
+ }
+
+ qes_sequtil_revcomp_inplace(outseq, len);
+ return outseq;
+}
+
+inline void
+qes_sequtil_revcomp_inplace (char *seq, size_t len)
+{
+ size_t iii;
+ /* Trim trailing whitespace */
+ while (len > 0 && isspace(seq[len - 1])) {
+ seq[--len] = '\0';
+ }
+ for (iii = 0; iii < len && seq[iii] != '\0'; iii++) {
+ size_t endpos = len - iii - 1;
+ char endchar = seq[endpos];
+ if (seq[iii] == 'a' || seq[iii] == 'A') seq[endpos] = 'T';
+ else if (seq[iii] == 'c' || seq[iii] == 'C') seq[endpos] = 'G';
+ else if (seq[iii] == 'g' || seq[iii] == 'G') seq[endpos] = 'C';
+ else if (seq[iii] == 't' || seq[iii] == 'T') seq[endpos] = 'A';
+ else seq[endpos] = 'N';
+ if (endchar == 'a' || endchar == 'A') seq[iii] = 'T';
+ else if (endchar == 'c' || endchar == 'C') seq[iii] = 'G';
+ else if (endchar == 'g' || endchar == 'G') seq[iii] = 'C';
+ else if (endchar == 't' || endchar == 'T') seq[iii] = 'A';
+ else seq[iii] = 'N';
+ }
+}
diff --git a/src/libqes/src/qes_sequtil.h b/src/libqes/src/qes_sequtil.h
new file mode 100644
index 0000000..11873f3
--- /dev/null
+++ b/src/libqes/src/qes_sequtil.h
@@ -0,0 +1,23 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_sequtil.h
+ *
+ * Description: Sequence utility functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_SEQUTIL_H
+#define QES_SEQUTIL_H
+
+#include <qes_util.h>
+
+
+extern char qes_sequtil_translate_codon(const char *codon);
+extern char *qes_sequtil_revcomp(const char *seq, size_t len);
+extern void qes_sequtil_revcomp_inplace(char *seq, size_t len);
+
+#endif /* QES_SEQUTIL_H */
diff --git a/src/libqes/src/qes_str.c b/src/libqes/src/qes_str.c
new file mode 100644
index 0000000..2bf83cf
--- /dev/null
+++ b/src/libqes/src/qes_str.c
@@ -0,0 +1,36 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_str.c
+ *
+ * Description: String handling functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_str.h"
+
+
+void
+qes_str_print (const struct qes_str *str, FILE *stream)
+{
+ if (qes_str_ok(str)) {
+ fprintf(stream, "%s", str->str);
+ }
+}
+
+void
+qes_str_destroy_cp (struct qes_str *str)
+{
+ if (str != NULL) qes_free(str->str);
+}
+
+void
+qes_str_destroy (struct qes_str *str)
+{
+ qes_str_destroy_cp(str);
+ qes_free(str);
+}
+
diff --git a/src/libqes/src/qes_str.h b/src/libqes/src/qes_str.h
new file mode 100644
index 0000000..1066b90
--- /dev/null
+++ b/src/libqes/src/qes_str.h
@@ -0,0 +1,135 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_str.h
+ *
+ * Description: String handling functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_STR_H
+#define QES_STR_H
+
+#include <qes_util.h>
+
+struct qes_str {
+ char *str;
+ size_t len;
+ size_t capacity;
+};
+
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_ok
+Parameters: const struct qes_str *str: `struct qes_str` ref to check.
+Description: Checks if a string is OK to use, i.e. checks that `str->str` is
+ a valid `char` array.
+Returns: An `int` that evaluates to true or false.
+ *===========================================================================*/
+static inline int
+qes_str_ok (const struct qes_str *str)
+{
+ return str != NULL && str->str != NULL && str->capacity > 0;
+}
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_init
+Parameters: struct qes_str *str: String to initialise (normally on the stack).
+ size_t len: Initial capacity of `struct qes_str`.
+Description: Initialise a `struct qes_str` (typically on the stack) with room for
+ `len` characters.
+Returns: void
+ *===========================================================================*/
+static inline void
+qes_str_init (struct qes_str *str, size_t capacity)
+{
+ if (str == NULL) return;
+ str->len = 0;
+ str->str = qes_calloc(capacity, sizeof(*str->str));
+ str->capacity = capacity;
+}
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_create
+Parameters: size_t len: Initial capacity of `struct qes_str`.
+Description: Create a `struct qes_str` on the heap with room for `len` characters.
+Returns: `struct qes_str *` Pointer to a memory address.
+ *===========================================================================*/
+static inline struct qes_str *
+qes_str_create (size_t capacity)
+{
+ struct qes_str *str = qes_calloc(1, sizeof(*str));
+
+ /* We don't worry about NULL here. qes_str_init will return before
+ * derefencing and we'll return NULL below. */
+ qes_str_init(str, capacity);
+ return str;
+}
+
+static inline int
+qes_str_fill_charptr (struct qes_str *str, const char *cp, size_t len)
+{
+ if (str == NULL || cp == NULL) return 0;
+ if (len == 0) {
+ len = strlen(cp);
+ }
+ if (str->capacity < len + 1) {
+ while (str->capacity < len + 1) {
+ str->capacity = qes_roundupz(str->capacity);
+ }
+ str->str = qes_realloc(str->str, str->capacity * sizeof(*str->str));
+ }
+ /* FIXME: check for null after realloc */
+ memcpy(str->str, cp, len);
+ str->str[len] = '\0';
+ str->len = len;
+ return 1;
+}
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_nullify
+Paramters: struct qes_str *str: `struct qes_str` to nullify.
+Description: Invalidates a `struct qes_str` without freeing the `char []`.
+Returns: int: 0 on success, otherwise 1.
+ *===========================================================================*/
+static inline int
+qes_str_nullify (struct qes_str *str)
+{
+ if (!qes_str_ok(str)) return 1;
+ str->str[0] = '\0';
+ str->len = 0;
+ return 0;
+}
+
+static inline int
+qes_str_copy (struct qes_str *dest, const struct qes_str *src)
+{
+ if (!qes_str_ok(src) || dest == NULL) return 1;
+ if (!qes_str_ok(dest)) qes_str_init(dest, src->capacity);
+ memcpy(dest->str, src->str, src->capacity);
+ return 0;
+}
+
+extern void qes_str_print (const struct qes_str *str, FILE *stream);
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_destroy
+Paramters: struct qes_str *: `struct qes_str` to destroy.
+Description: Frees `str->str` and the struct qes_str struct itself.
+Returns: void
+ *===========================================================================*/
+extern void qes_str_destroy (struct qes_str *str);
+
+/*=== FUNCTION ============================================================*
+Name: qes_str_destroy_cp
+Paramters: struct qes_str *: String to destrop
+Description: Frees `str->str` without freeing the struct qes_str struct
+ itself. For use on `struct qes_str`s allocated on the stack.
+Returns: void
+ *===========================================================================*/
+extern void qes_str_destroy_cp (struct qes_str *str);
+
+#endif /* QES_STR_H */
diff --git a/src/libqes/src/qes_util.c b/src/libqes/src/qes_util.c
new file mode 100644
index 0000000..bd14340
--- /dev/null
+++ b/src/libqes/src/qes_util.c
@@ -0,0 +1,59 @@
+/*
+ * ============================================================================
+ *
+ * Filename: qes_util.c
+ *
+ * Description: Wrappers around std library functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "qes_util.h"
+
+
+/* Pull LIBQES_VERSION in from qes_config.h */
+const char *libqes_version = LIBQES_VERSION;
+
+/* Valid non-function to pass to libqes functions */
+void
+errnil (QES_ERRFN_ARGS)
+{
+ (void) (msg);
+ (void) (file);
+ (void) (line);
+}
+
+/* Function to pass to libqes functions which prints out errors to stderr */
+void
+errprint (QES_ERRFN_ARGS)
+{
+ char msg_fmt[1<<8] = "";
+ va_list args;
+ if (msg == NULL) {
+ msg = "GENERIC ERROR WITH NO MESSAGE";
+ }
+ va_start (args, line);
+ vsnprintf(msg_fmt, 1<<8, msg, args);
+ va_end (args);
+ fprintf(stderr, "[%s: %d]: %s\n", file, line, msg_fmt);
+}
+
+/* Function to pass to libqes functions which prints out errors to stderr and
+ calls `exit(EXIT_FAILURE)` */
+void
+errprintexit (QES_ERRFN_ARGS)
+{
+ char msg_fmt[1<<8] = "";
+ va_list args;
+ if (msg == NULL) {
+ msg = "GENERIC ERROR WITH NO MESSAGE";
+ }
+ va_start (args, line);
+ vsnprintf(msg_fmt, 1<<8, msg, args);
+ va_end (args);
+ fprintf(stderr, "[%s: %d]: %s\n", file, line, msg_fmt);
+ QES_EXIT_FN(EXIT_FAILURE);
+}
+
diff --git a/src/libqes/src/qes_util.h b/src/libqes/src/qes_util.h
new file mode 100644
index 0000000..961c581
--- /dev/null
+++ b/src/libqes/src/qes_util.h
@@ -0,0 +1,236 @@
+/*
+ ============================================================================
+ *
+ * Filename: qes_util.h
+ *
+ * Description: Wrappers around std library functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef QES_UTIL_H
+#define QES_UTIL_H
+
+
+/* ##### HEADER FILE INCLUDES ########################################## */
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "qes_config.h"
+#include "qes_compat.h"
+#include "qes_libgnu.h"
+
+
+/*
+ * Cross-platform bollocks. Thanks windows.
+ */
+
+#if defined(WIN32) || defined(_WIN32)
+#include <windows.h>
+#define QES_PATHSEP "\\"
+#else
+#define QES_PATHSEP "/"
+#include <unistd.h>
+#endif
+
+/*
+ * Misc constants
+ */
+
+extern const char *libqes_version;
+
+#define QES_MAX_FN_LEN (1<<16)
+/* Size of buffers for file IO */
+#define QES_FILEBUFFER_LEN (16384)
+/* Starting point for allocing a char pointer. Set to slightly larger than the
+ standard size of whatever you're reading in. */
+#define __INIT_LINE_LEN (128)
+
+/*
+ * Macro helpers from tor
+ */
+
+/* Expands to a syntactically valid empty statement. */
+#define STMT_NIL (void)0
+
+/* Expands to a syntactically valid empty statement, explicitly (void)ing its
+ * argument. */
+#define STMT_VOID(a) while (0) { (void)(a); }
+
+/* STMT_BEGIN and STMT_END are used to wrap blocks inside macros so that
+ * the macro can be used as if it were a single C statement. */
+#ifdef __GNUC__
+ #define STMT_BEGIN (void) ({
+ #define STMT_END })
+#elif defined(sun) || defined(__sun__)
+ #define STMT_BEGIN if (1) {
+ #define STMT_END } else STMT_NIL
+#else
+ #define STMT_BEGIN do {
+ #define STMT_END } while (0)
+#endif
+
+/* This can be helpful in some macros, particularly with #pragma */
+#ifndef STRINGIFY
+ #define STRINGIFY(a) #a
+#endif
+
+/*
+ * Error handling functions
+ */
+
+/* use the stdlib exit function by default, during testing we can #define this
+ * to some kind of error handler if we need to. */
+#ifndef QES_EXIT_FN
+ #define QES_EXIT_FN exit
+#endif
+
+
+/* By default, we use this error handler. At compile or include time, we can
+ * chose another more appropriate one if we need to. */
+#ifndef QES_DEFAULT_ERR_FN
+ #define QES_DEFAULT_ERR_FN errprintexit
+#endif
+
+
+#define QES_ERRFN_ARGS const char *msg, const char *file, int line, ...
+void errnil(QES_ERRFN_ARGS);
+void errprint (QES_ERRFN_ARGS);
+void errprintexit (QES_ERRFN_ARGS) __attribute__ ((noreturn));
+typedef void (*qes_errhandler_func) (const char*, const char *, int, ...);
+
+/* qes_roundupz:
+ * Round up a `size_t` to the next highest power of two.
+ */
+/* Flogged from http://stackoverflow.com/a/1322548 and
+ http://graphics.stanford.edu/~seander/bithacks.html, and kseq.h */
+static inline size_t
+qes_roundupz (size_t sz)
+{
+ /* Decrement v only if v is not already a power of 2 */
+ /* I.e, roundup things already a power of 2 */
+ if ((sz & (sz - 1)) != 0) sz--;
+ /* mask all bits below MSB to 1 */
+ sz |= sz>>1;
+ sz |= sz>>2;
+ sz |= sz>>4;
+ sz |= sz>>8;
+ sz |= sz>>16;
+#if UINTPTR_MAX == 0xffffffffffffffff /* 64-bit system */
+ sz |= sz>>32;
+#endif
+ return sz + 1;
+}
+
+static inline uint32_t
+qes_roundup32 (uint32_t u32)
+{
+ /* Roundup things already a power of 2 */
+ if ((u32 & (u32 - 1)) != 0) u32--;
+ /* mask all bits below MSB to 1 */
+ u32 |= u32>>1;
+ u32 |= u32>>2;
+ u32 |= u32>>4;
+ u32 |= u32>>8;
+ u32 |= u32>>16;
+ return u32 + 1;
+}
+
+static inline uint64_t
+qes_roundup64 (uint64_t u64)
+{
+ /* Roundup things already a power of 2 */
+ if ((u64 & (u64 - 1)) != 0) u64--;
+ /* mask all bits below MSB to 1 */
+ u64 |= u64>>1;
+ u64 |= u64>>2;
+ u64 |= u64>>4;
+ u64 |= u64>>8;
+ u64 |= u64>>16;
+ u64 |= u64>>32;
+ return u64 + 1;
+}
+
+
+/* INLINE FUNCTIONS */
+
+/* Memory allocation/deallocation */
+static inline void *
+qes_calloc_ (size_t n, size_t size, qes_errhandler_func onerr, const char *file,
+ int line)
+{
+ void *ret = calloc(n, size);
+ if (ret == NULL) {
+ (*onerr)("calloc returned NULL -- Out of memory", file, line);
+ return NULL;
+ } else {
+ return ret;
+ }
+}
+#define qes_calloc(n, sz) \
+ qes_calloc_(n, sz, QES_DEFAULT_ERR_FN, __FILE__, __LINE__)
+#define qes_calloc_errnil(n, sz) \
+ qes_calloc_(n, sz, errnil, __FILE__, __LINE__)
+#define qes_calloc_errprint(n, sz) \
+ qes_calloc_(n, sz, errprint, __FILE__, __LINE__)
+#define qes_calloc_errprintexit(n, sz) \
+ qes_calloc_(n, sz, errprintexit, __FILE__, __LINE__)
+
+static inline void *
+qes_malloc_ (size_t size, qes_errhandler_func onerr, const char *file, int line)
+{
+ void *ret = malloc(size);
+ if (ret == NULL) {
+ (*onerr)("malloc returned NULL -- Out of memory", file, line);
+ return NULL;
+ } else {
+ return ret;
+ }
+}
+#define qes_malloc(sz) \
+ qes_malloc_(sz, QES_DEFAULT_ERR_FN, __FILE__, __LINE__)
+#define qes_malloc_errnil(sz) \
+ qes_malloc_(sz, errnil, __FILE__, __LINE__)
+#define qes_malloc_errprint(sz) \
+ qes_malloc_(sz, errprint, __FILE__, __LINE__)
+#define qes_malloc_errprintexit(sz) \
+ qes_malloc_(sz, errprintexit, __FILE__, __LINE__)
+
+static inline void *
+qes_realloc_ (void *data, size_t size, qes_errhandler_func onerr, const char *file,
+ int line)
+{
+ void *ret = realloc(data, size);
+ if (ret == NULL) {
+ (*onerr)("realloc returned NULL -- Out of memory", file, line);
+ return NULL;
+ } else {
+ return ret;
+ }
+}
+
+#define qes_realloc(ptr, sz) \
+ qes_realloc_(ptr, sz, QES_DEFAULT_ERR_FN, __FILE__, __LINE__)
+#define qes_realloc_errnil(ptr, sz) \
+ qes_realloc_(ptr, sz, errnil, __FILE__, __LINE__)
+#define qes_realloc_errprint(ptr, sz) \
+ qes_realloc_(ptr, sz, errprint, __FILE__, __LINE__)
+#define qes_realloc_errprintexit(ptr, sz) \
+ qes_realloc_(ptr, sz, errprintexit, __FILE__, __LINE__)
+#define qes_free(data) \
+ STMT_BEGIN \
+ if (data != NULL) { \
+ free(data); \
+ data = NULL; \
+ } \
+ STMT_END
+
+#endif /* QES_UTIL_H */
diff --git a/src/libqes/test/CMakeLists.txt b/src/libqes/test/CMakeLists.txt
new file mode 100644
index 0000000..fdf2ed1
--- /dev/null
+++ b/src/libqes/test/CMakeLists.txt
@@ -0,0 +1,36 @@
+## Compile tests, & set up coverage
+SET(COMMON_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/helpers.c)
+FILE(GLOB TEST_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/test*.c)
+SET(TEST_SRCS ${COMMON_SRCS} ${TEST_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/tinytest/tinytest.c)
+ADD_EXECUTABLE(test_libqes ${TEST_SRCS})
+TARGET_LINK_LIBRARIES(test_libqes qes ${LIBQES_DEPENDS_LIBS})
+IF (CMAKE_BUILD_TYPE STREQUAL "Coverage")
+ SETUP_TARGET_FOR_COVERAGE(coverage test_libqes coverage src)
+ENDIF()
+ADD_TEST(NAME run_test_libqes
+ COMMAND ${CMAKE_BINARY_DIR}/bin/test_libqes ${CMAKE_BINARY_DIR})
+
+# Demos
+ADD_EXECUTABLE(log_demo ${CMAKE_CURRENT_SOURCE_DIR}/logdemo.c)
+TARGET_LINK_LIBRARIES(log_demo qes ${LIBQES_DEPENDS_LIBS})
+ADD_TEST(NAME run_log_demo
+ COMMAND ${CMAKE_BINARY_DIR}/bin/log_demo)
+
+# Benchmarking:
+ADD_EXECUTABLE(bench_libqes ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks.c ${COMMON_SRCS})
+TARGET_LINK_LIBRARIES(bench_libqes qes ${LIBQES_DEPENDS_LIBS})
+ADD_TEST(NAME run_bench_libqes
+ COMMAND ${CMAKE_BINARY_DIR}/bin/bench_libqes
+ ${CMAKE_BINARY_DIR}/data/test.fastq
+ 50
+ qes_seqfile_write
+ kseq_parse_fq
+ gnu_getline
+ qes_seqfile_parse_fq
+ qes_file_readline_realloc)
+
+# Copy test files over to bin dir
+ADD_CUSTOM_COMMAND(TARGET test_libqes
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_SOURCE_DIR}/data
+ ${CMAKE_BINARY_DIR}/data)
diff --git a/src/libqes/test/benchmarks.c b/src/libqes/test/benchmarks.c
new file mode 100644
index 0000000..c088a61
--- /dev/null
+++ b/src/libqes/test/benchmarks.c
@@ -0,0 +1,295 @@
+/*
+ * ============================================================================
+ *
+ * Filename: benchmarks.c
+ *
+ * Description: Some benchmarks
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdlib.h>
+#include <qes_file.h>
+#include <qes_seqfile.h>
+#ifdef ZLIB_FOUND
+# include <zlib.h>
+#else
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
+#include "helpers.h"
+#include "kseq.h"
+
+
+void bench_qes_file_readline_realloc_file(int silent);
+void bench_qes_file_readline_file(int silent);
+#ifdef GELINE_FOUND
+void bench_gnu_getline_file(int silent);
+#endif
+void bench_qes_seqfile_parse_fq(int silent);
+void bench_kseq_parse_fq(int silent);
+void bench_qes_seqfile_write(int silent);
+#ifdef OPENMP_FOUND
+void bench_qes_seqfile_par_iter_fq_macro(int silent);
+#endif
+
+
+#ifdef ZLIB_FOUND
+KSEQ_INIT(gzFile, gzread)
+#else
+KSEQ_INIT(int, read)
+#endif
+
+static char *infile;
+
+typedef struct __bench {
+ const char *name;
+ void (*fn)(int silent);
+} bench_t;
+
+void
+bench_qes_file_readline_realloc_file(int silent)
+{
+ size_t bsz = 1<<4;
+ char *buf = malloc(bsz);
+ ssize_t len = 0;
+ off_t flen = 0;
+ struct qes_file *file = qes_file_open(infile, "r");
+
+ assert(buf != NULL);
+ while ((len = qes_file_readline_realloc(file, &buf, &bsz)) != EOF) {
+ flen += len;
+ }
+ if (!silent)
+ printf("[qes_file_readline_realloc]\tFile of %lu chars\n",
+ (long unsigned)flen);
+ qes_file_close(file);
+ free(buf);
+}
+
+void
+bench_qes_file_readline_file(int silent)
+{
+ size_t bsz = 1<<10;
+ char buf[bsz];
+ ssize_t len = 0;
+ off_t flen = 0;
+
+ struct qes_file *file = qes_file_open(infile, "r");
+ while ((len = qes_file_readline(file, buf, bsz)) != EOF) {
+ flen += len;
+ }
+ if (!silent)
+ printf("[qes_file_readline]\t\tFile of %lu chars\n",
+ (long unsigned)flen);
+ qes_file_close(file);
+}
+
+#ifdef GELINE_FOUND
+void
+bench_gnu_getline_file(int silent)
+{
+ size_t bsz = 1<<4;
+ char *buf = malloc(bsz);
+ ssize_t len = 0;
+ off_t flen = 0;
+ FILE *file = fopen(infile, "r");
+
+ assert(buf != NULL);
+ while ((len = getline(&buf, &bsz, file)) != EOF) {
+ flen += len;
+ }
+ if (!silent)
+ printf("[getline]\t\tFile of %lu chars\n",
+ (long unsigned)flen);
+ fclose(file);
+ free(buf);
+}
+#endif
+
+
+#ifdef OPENMP_FOUND
+void
+bench_qes_seqfile_par_iter_fq_macro(int silent)
+{
+ struct qes_seqfile *sf = qes_seqfile_create(infile, "r");
+ size_t total_len = 0;
+
+ QES_SEQFILE_ITER_PARALLEL_SINGLE_BEGIN(sf, seq, seq_len, shared(total_len))
+ #pragma omp critical
+ {
+ total_len += seq->seq.len;
+ }
+ QES_SEQFILE_ITER_PARALLEL_SINGLE_END(seq)
+
+ if (!silent) {
+ printf("[qes_seqfile_iter_fq_macro] Total seq len %lu\n",
+ (long unsigned)total_len);
+ }
+ qes_seqfile_destroy(sf);
+}
+#endif
+
+void
+bench_qes_seqfile_parse_fq(int silent)
+{
+ struct qes_seq *seq = qes_seq_create();
+ struct qes_seqfile *sf = qes_seqfile_create(infile, "r");
+ ssize_t res = 0;
+ size_t n_recs = 0;
+ size_t seq_len = 0;
+
+ while (res != EOF) {
+ res = qes_seqfile_read(sf, seq);
+ if (res < 1) {
+ break;
+ }
+ seq_len += res;
+ n_recs++;
+ }
+ if (!silent) {
+ printf("[qes_seqfile_fq] Total seq len %lu\n",
+ (long unsigned)seq_len);
+ }
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+}
+
+void
+bench_kseq_parse_fq(int silent)
+{
+#ifdef ZLIB_FOUND
+ gzFile fp = gzopen(infile, "r");
+#else
+ int fp = open(infile, O_RDONLY);
+#endif
+ kseq_t *seq = kseq_init(fp);
+ ssize_t res = 0;
+ size_t n_recs = 0;
+ size_t seq_len = 0;
+
+ while ((res = kseq_read(seq)) >= 0) {
+ seq_len += res;
+ n_recs++;
+ }
+ if (!silent) {
+ printf("[kseq_fq] Total seq len %lu\n",
+ (long unsigned) seq_len);
+ }
+ kseq_destroy(seq);
+#ifdef ZLIB_FOUND
+ gzclose(fp);
+#else
+ close(fp);
+#endif
+}
+
+void
+bench_qes_seqfile_write(int silent)
+{
+ struct qes_seq *seq = qes_seq_create();
+ ssize_t res = 0;
+ struct qes_seqfile *sf = NULL;
+ char *fname = tmpnam(NULL);
+ size_t iii = 0;
+
+ /* Make a seq to write */
+ qes_seq_fill_name(seq, "HWI-TEST", 8);
+ qes_seq_fill_comment(seq, "testseq 1 2 3", 13);
+ qes_seq_fill_seq(seq, "ACTCAATT", 8);
+ qes_seq_fill_qual(seq, "IIIIIIII", 8);
+ /* Setup file for writing */
+ sf = qes_seqfile_create(fname, "wT");
+ qes_seqfile_set_format(sf, FASTQ_FMT);
+ for (iii = 0; iii < 1<<11; iii++) {
+ res += qes_seqfile_write(sf, seq);
+ }
+ if (!silent) {
+ printf("[qes_seqfile_write] Total file len %lu to %s\n",
+ (long unsigned)res, fname);
+ }
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+ remove(fname);
+
+}
+
+static const bench_t benchmarks[] = {
+ { "qes_file_readline", &bench_qes_file_readline_file},
+ { "qes_file_readline_realloc", &bench_qes_file_readline_realloc_file},
+#ifdef GELINE_FOUND
+ { "gnu_getline", &bench_gnu_getline_file},
+#endif
+ { "qes_seqfile_parse_fq", &bench_qes_seqfile_parse_fq},
+#ifdef OPENMP_FOUND
+ { "qes_seqfile_par_iter_fq_macro", &bench_qes_seqfile_par_iter_fq_macro},
+#endif
+ { "kseq_parse_fq", &bench_kseq_parse_fq},
+ { "qes_seqfile_write", &bench_qes_seqfile_write},
+ { NULL, NULL}
+};
+
+int
+main (int argc, char *argv[])
+{
+ bench_t thisbench;
+ clock_t start, end;
+ size_t iii = 0;
+ int rnds = 0;
+ size_t nbench = 0;
+
+ if (argc == 1) {
+ fprintf(stderr, "USAGE:\nbench <file> <rounds> <bench> [<bench> ...]\n\n");
+ fprintf(stderr, "\nAvalilable benchmarks are:\n");
+ nbench = 0;
+ while (1) {
+ thisbench = benchmarks[nbench++];
+ if ((thisbench.name && thisbench.fn)) {
+ fprintf(stderr, "%s\n", thisbench.name);
+ } else {
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ if (argc < 4) {
+ fprintf(stderr, "USAGE:\nbench <file> <rounds> <bench> [<bench> ...]\n\n");
+ return EXIT_FAILURE;
+ } else {
+ infile = strdup(argv[1]);
+ rnds = atoi(argv[2]);
+ printf("Begining benchmarks.\n");
+ printf("---------------------------------------------------------------------\n");
+ }
+ for (iii = 3; iii < (unsigned int) argc; iii++) {
+ nbench = 0;
+ while (1) {
+ thisbench = benchmarks[nbench++];
+ if (!(thisbench.name && thisbench.fn)) {
+ fprintf(stderr, "bad benchmark %s\n", argv[iii]);
+ break;
+ }
+ if (strcmp(argv[iii], thisbench.name) == 0) {
+ int rnd = 0;
+ start = clock();
+ for (rnd = 0; rnd<rnds; rnd++) {
+ (*thisbench.fn)(rnd != rnds - 1);
+ }
+ end = clock();
+ printf("Benchmark %s took %0.6fs per round [%d rounds]\n",
+ thisbench.name,
+ (float)(end - start) / (float)(CLOCKS_PER_SEC * rnds),
+ rnds);
+ printf("---------------------------------------------------------------------\n");
+ break;
+ }
+ }
+ }
+ free(infile);
+ return EXIT_SUCCESS;
+} /* ---------- end of function main ---------- */
diff --git a/src/libqes/test/data/bad_diff_lens.fastq b/src/libqes/test/data/bad_diff_lens.fastq
new file mode 100644
index 0000000..c4dac0f
--- /dev/null
+++ b/src/libqes/test/data/bad_diff_lens.fastq
@@ -0,0 +1,4 @@
+ at HWI-ST960:105:D10GVACXX:2:1101:1151:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGACATTGAATCTATATGT
++
+JJJJJIJHIJCC#4ADFFHHHGHJJJJIJJJ
diff --git a/src/libqes/test/data/bad_nohdr.fastq b/src/libqes/test/data/bad_nohdr.fastq
new file mode 100644
index 0000000..8a1eac8
--- /dev/null
+++ b/src/libqes/test/data/bad_nohdr.fastq
@@ -0,0 +1,3 @@
+CACGATCAGATCAANGACATTGAATCTATATGT
++
+JJJJJJJIJHIJCC#4ADFFHHHGHJJJJIJJJ
diff --git a/src/libqes/test/data/bad_noqual.fastq b/src/libqes/test/data/bad_noqual.fastq
new file mode 100644
index 0000000..67d3a81
--- /dev/null
+++ b/src/libqes/test/data/bad_noqual.fastq
@@ -0,0 +1,3 @@
+ at HWI-ST960:105:D10GVACXX:2:1101:1151:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGACATTGAATCTATATGT
++
diff --git a/src/libqes/test/data/bad_noqualhdrchr.fastq b/src/libqes/test/data/bad_noqualhdrchr.fastq
new file mode 100644
index 0000000..9f91fe1
--- /dev/null
+++ b/src/libqes/test/data/bad_noqualhdrchr.fastq
@@ -0,0 +1,4 @@
+ at HWI-ST960:105:D10GVACXX:2:1101:1151:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGACATTGAATCTATATGT
+
+CACGATCAGATCAANGACATTGAATCTATATGT
diff --git a/src/libqes/test/data/bad_noqualhdreol.fastq b/src/libqes/test/data/bad_noqualhdreol.fastq
new file mode 100644
index 0000000..5aaf3cc
--- /dev/null
+++ b/src/libqes/test/data/bad_noqualhdreol.fastq
@@ -0,0 +1,3 @@
+ at HWI-ST960:105:D10GVACXX:2:1101:1151:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGACATTGAATCTATATGT
++HWI-BLERG
\ No newline at end of file
diff --git a/src/libqes/test/data/empty.fastq b/src/libqes/test/data/empty.fastq
new file mode 100644
index 0000000..b516b2c
--- /dev/null
+++ b/src/libqes/test/data/empty.fastq
@@ -0,0 +1 @@
+@
\ No newline at end of file
diff --git a/src/libqes/test/data/empty.txt b/src/libqes/test/data/empty.txt
new file mode 100644
index 0000000..e69de29
diff --git a/src/libqes/test/data/log_test.txt b/src/libqes/test/data/log_test.txt
new file mode 100644
index 0000000..8254f87
--- /dev/null
+++ b/src/libqes/test/data/log_test.txt
@@ -0,0 +1,2 @@
+Hello World
+Hello World
diff --git a/src/libqes/test/data/loremipsum.txt b/src/libqes/test/data/loremipsum.txt
new file mode 100644
index 0000000..eaf1478
--- /dev/null
+++ b/src/libqes/test/data/loremipsum.txt
@@ -0,0 +1,11 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ornare tortor et
+rhoncus iaculis. Sed suscipit, arcu nec elementum vestibulum, tortor tortor
+dictum dui, eu sodales magna orci eu libero. Cras commodo, ligula tempor auctor
+vulputate, eros urna gravida eros, eget congue leo quam quis mi. Curabitur
+luctus augue nibh, eget vehicula augue commodo eget. Donec condimentum molestie
+adipiscing. In non purus lacus. Nam nec mollis mauris. Donec rhoncus, diam sit
+amet rhoncus viverra, lectus risus tincidunt ipsum, in dignissim justo purus
+eget enim. Fusce congue nulla egestas est auctor faucibus. Integer feugiat
+molestie leo, a interdum neque pretium nec. Etiam sit amet nibh leo.
+
+End of lorem ipsum.
diff --git a/src/libqes/test/data/loremipsum.txt.gz b/src/libqes/test/data/loremipsum.txt.gz
new file mode 100644
index 0000000..cb768d6
Binary files /dev/null and b/src/libqes/test/data/loremipsum.txt.gz differ
diff --git a/src/libqes/test/data/nocomment.fasta b/src/libqes/test/data/nocomment.fasta
new file mode 100644
index 0000000..732a2b7
--- /dev/null
+++ b/src/libqes/test/data/nocomment.fasta
@@ -0,0 +1,5 @@
+>HWI-ST960:105:D10GVACXX:2:1101:1122:2186
+CACACTTGAA
+TCCAGTTTAA
+AGTTAACTCA
+TTG
diff --git a/src/libqes/test/data/random.bin b/src/libqes/test/data/random.bin
new file mode 100644
index 0000000..9f95426
Binary files /dev/null and b/src/libqes/test/data/random.bin differ
diff --git a/src/libqes/test/data/test.fasta b/src/libqes/test/data/test.fasta
new file mode 100644
index 0000000..f814857
--- /dev/null
+++ b/src/libqes/test/data/test.fasta
@@ -0,0 +1,4061 @@
+>HWI-ST960:105:D10GVACXX:2:1101:1122:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCAGTTTAA
+AGTTAACTCA
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:1229:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTGAGTTT
+TTGGACTGTA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:1175:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAATTGT
+CACTGTTTCA
+CCC
+>HWI-ST960:105:D10GVACXX:2:1101:1175:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGTGACT
+CTGTTCCTGT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:1204:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCACAGA
+GCAGCAGTAT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:1237:2239 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTACACAC
+GTATATGCAA
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:1123:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATAATGT
+GGTATTAGTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:1155:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGCCACTG
+AACTAAAAAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:1443:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTACCAAAG
+TCTGAATGAT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:1360:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCCGGCTCT
+GTCTCTCTCT
+CCC
+>HWI-ST960:105:D10GVACXX:2:1101:1272:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCATTTA
+GAGGAAGGAG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:1423:2185 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGACGT
+CAAATTATGC
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:1398:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAAAAAAA
+AAAGAATAAA
+GAA
+>HWI-ST960:105:D10GVACXX:2:1101:1333:2199 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATTACAA
+AGTTTACATC
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:1388:2214 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTCGTCT
+TCCATTTCTA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:1366:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTAT
+ATGCTGTGGT
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:1297:2232 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATTCATGT
+TGATATATTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:1374:2245 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTGTGTGT
+CTGAAGTAGT
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:1277:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGTTTCA
+GACTTCGAGA
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:1425:2250 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATATAC
+TTCACAACTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:1601:2174 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTTTTACGT
+AGACGATGTG
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:1581:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCAGTTGAG
+GAACTATTGT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:1717:2186 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAATCTTTG
+TACTGTTGAA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:1538:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACTGTTT
+GTGTCAATCA
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:1687:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGTCCTTC
+GGATCACTCA
+A
+>HWI-ST960:105:D10GVACXX:2:1101:1589:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGAGCACA
+AAGATGATCA
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:1611:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGAGAGT
+AGCTCTGTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:1672:2207 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATATTTG
+ATACATCGGT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:1595:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTCTGACT
+GATGAACATA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:1706:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTGCAAT
+TAGTGCAACT
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:1575:2228 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGTTTGAGA
+CTCTATCTTA
+CCT
+>HWI-ST960:105:D10GVACXX:2:1101:1557:2229 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTTTTGT
+GTGTACTTGT
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:1747:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATATACA
+ATTGTGGACT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:1921:2172 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTTAGA
+ACTCTTTTCC
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:1992:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTGTTGG
+GGTAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:1925:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAAGTGT
+GATTCTTTTG
+G
+>HWI-ST960:105:D10GVACXX:2:1101:1792:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAAAGTC
+ATGTCTTTGT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:1771:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGTGACCG
+AGAAATGTTT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:1915:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTCAGTCT
+AACTAAAGTA
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:1899:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCACTAATA
+CAATTGTTGC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:2049:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTCTTG
+TACTACAGTG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:2035:2185 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGTAGAA
+TTCAGAATGT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:2214:2203 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTGTACACG
+GCTTAATTTA
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:2244:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCGGTTTGA
+GTGTTGCAAA
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:2185:2223 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAACAAGGT
+CGTTGTAGTA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:2067:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTCCATA
+GATTGTAGCC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:2032:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTGTTA
+GTTACGCTTT
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:2011:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAATAT
+GATATGAAAA
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:2444:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTCCTGT
+GATTTGCAAT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:2254:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCCATAAAA
+AGTCTCTACA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:2448:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGAAGAAA
+AAGATGACCA
+GCT
+>HWI-ST960:105:D10GVACXX:2:1101:2342:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATGTTCG
+ACTGTGAACC
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:2268:2215 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCAATATCAG
+AACTCGTTAT
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:2411:2223 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCGCAACTGT
+AGCAAGAAGA
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:2292:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTACTT
+AAAGAGCCCT
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:2448:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATGAGTGT
+AGGCTTACTT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:2389:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCGATCT
+GGTTTGTAGA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:2675:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAAGTGA
+ACTCTGTGCG
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:2548:2190 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATCTTCT
+GTTGACTCAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:2610:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAGTAT
+CAATTGAACT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:2657:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATATATA
+TATAAATGCA
+GAC
+>HWI-ST960:105:D10GVACXX:2:1101:2576:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATATTTTT
+CCCACTGTGT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:2626:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGAGAACTC
+TAGAAACCTG
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:2660:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTACAAT
+GTACTGGAAA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:2509:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCAAACTT
+TATGTAAACT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:2536:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATACCAA
+ATAGAATTTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:2584:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGTGCCT
+GGATTAATAT
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:2674:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGCAACT
+GCAAATTCTG
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:2718:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACGGAACC
+AGTGACCGTC
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:2630:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTACTTGA
+ACAGGATCTG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:2869:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTCCGATG
+ATGATCAAAT
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:2917:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGTCTCG
+CTTATGACTA
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:2789:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATATTGGT
+CTGTATTGTG
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:2841:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAGAACTA
+ACAGATATAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:3211:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGTAAT
+GTAGTCTTTA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:3145:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGGCTGTG
+GAGTAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:3082:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTGTGTT
+GGCGTTTTAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:3160:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTTGTTG
+GCCAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:3135:2214 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGACAGGAG
+AGGTGATCGG
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:3213:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTTCTGT
+TGAAGGAGCT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:3036:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATATAC
+TTCACAACTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:3140:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGCAAATA
+AGTCAAAACT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:3106:2228 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTTAGCTCG
+ACCTAACACT
+T
+>HWI-ST960:105:D10GVACXX:2:1101:3085:2237 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTCATCAAC
+TTTGTCTCTG
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:3151:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATTCCAT
+GTACTTACAT
+TCC
+>HWI-ST960:105:D10GVACXX:2:1101:3041:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGTAATAC
+CTTTTATATA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:3218:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGCCCAAA
+CTGCATGCAC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3440:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGATT
+GAAGGGAGCT
+C
+>HWI-ST960:105:D10GVACXX:2:1101:3302:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAAGTCAT
+GACTCATGAG
+CTA
+>HWI-ST960:105:D10GVACXX:2:1101:3369:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTGTCAT
+ATTTGCGATG
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:3257:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTAAA
+CTCTCGTGTG
+GCT
+>HWI-ST960:105:D10GVACXX:2:1101:3285:2210 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGAGATGC
+AAAACAGTAG
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:3316:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAAATC
+TTAATCTCAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3597:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCCCCCG
+TGAGTTACTT
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:3651:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATATGTA
+GGCTAAAAAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:3568:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATTTATG
+TTTTGGACTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:3545:2181 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGTGTGT
+TGTGGTTTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3669:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTGTGTT
+GGCGTTTTAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:3587:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAAGTGT
+AGAATGCATA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:3570:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTGTAT
+GATTGAAGAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3530:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAACGAAA
+ACTATTTAAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3706:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGGCGAG
+TGTATCTCAA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:3775:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTACATTA
+AGGCAGTTCA
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:3902:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCACAAA
+TGAACTTAAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:3885:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTACCTACT
+CGTCGTACAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:3807:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATCTCGG
+ACCAAAGAGA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:3780:2206 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGCATGTT
+GTGCACCGGC
+TCC
+>HWI-ST960:105:D10GVACXX:2:1101:3853:2215 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCTCCGATGA
+TGATCAAATC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3946:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAGTCT
+TTTGGTATTT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:3976:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTGTTCG
+GCTTTGGATT
+AAG
+>HWI-ST960:105:D10GVACXX:2:1101:3866:2227 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATACGAT
+ATGTATATGT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:3816:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAGGTCT
+TGTGTAGAAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:3779:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTTGAGT
+TTCGAGTTAT
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:3799:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTCTATC
+TACTACTTTT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:3759:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAACTAGTA
+TAGTCAGAAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:3912:2249 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCATGTGAAC
+AAGAACATAT
+CCT
+>HWI-ST960:105:D10GVACXX:2:1101:4099:2173 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTTGGCTCA
+TGAAGTAAAA
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:4193:2190 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACTTTACA
+GCTTCTTCTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:4045:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACTGTGTT
+GGCGTTTTAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:4171:2195 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCGAAGTTGA
+AGAACCTATA
+A
+>HWI-ST960:105:D10GVACXX:2:1101:4159:2232 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGTATCAAA
+CGTAGAGGCA
+G
+>HWI-ST960:105:D10GVACXX:2:1101:4186:2233 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTAGTCA
+GCTGCAACAC
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:4072:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAACACCA
+AACAACTCTT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:4053:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGAGG
+TTTGAGATAT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:4001:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCAAATGA
+GAACTTTGAA
+GGC
+>HWI-ST960:105:D10GVACXX:2:1101:4487:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAGCATGT
+AGTTTGATGA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:4487:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAATTGTT
+ACGCAACAAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:4428:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAATAT
+TTTTTCTATT
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:4264:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTTAATC
+TGAGTCTCTG
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:4422:2216 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACTTTACA
+CGACAAAATA
+A
+>HWI-ST960:105:D10GVACXX:2:1101:4332:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTCCGA
+GTACAACTTT
+GG
+>HWI-ST960:105:D10GVACXX:2:1101:4424:2238 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTAATCTTG
+TGTCGGCAGG
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:4369:2249 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGATAATGA
+TGATGAAAGA
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:4279:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATGTAG
+AACTCTTTGC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:4583:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAGTGA
+AATACACTCT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:4599:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTGTTATC
+GTGTCTGTAA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:4699:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTGCCTTC
+AAGTTAACTT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:4615:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGTCTTCT
+TCTTCTGTAT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:4505:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATCCTATG
+CTTTGGTCAT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:4515:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTACTTAG
+ACTCATGCTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:4695:2199 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAATGACTG
+TAACTTACTC
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:4586:2200 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATAGGA
+ATCTGTAACT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:4624:2201 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATTTGCG
+ATGTATCATG
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:4717:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTGGTT
+TATTTACATG
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:4738:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAGCTTC
+TCTGTTATGT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:4745:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTGATAT
+CTAAGCTTAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:4619:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTCAGATT
+TCTTACATTC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:4707:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCAGTGTTT
+GTCTGAACTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:4754:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATCGTCGT
+CAAGCCTGCC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:4768:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAAACTTCT
+CTGTTTAGTT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:4842:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAATCAT
+TATAGAGATG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:4964:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCAAGTCAT
+GACTCATGAG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:4787:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAACAAACT
+TGCATGTCGG
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:4867:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCTTCTTT
+CCAATCTTAT
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:4934:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTAG
+TAACTGAAAA
+CG
+>HWI-ST960:105:D10GVACXX:2:1101:4988:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTCTTTC
+TCGAGAAATC
+GG
+>HWI-ST960:105:D10GVACXX:2:1101:4973:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGCTGTAA
+TTACAGATTG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:4783:2210 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCGATGAATA
+CATCATGGTA
+GTG
+>HWI-ST960:105:D10GVACXX:2:1101:4861:2212 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATGTTT
+AGTTTAGAAG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:4929:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACTGTGT
+CTCATCACTC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:4966:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATATTCAA
+ACTCTTGGAC
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:4877:2249 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCCTTCCTAC
+TTGAAGAAGG
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:5029:2168 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTTTTGGTT
+CTGTAGACAC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:5174:2170 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATATAAT
+ATTCCCTAAG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:5153:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATACCCC
+GAAAATTAGA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:5078:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCTTGGTC
+TGGTGGTAAC
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:5182:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTTGTCA
+ACTTCAATTT
+CAG
+>HWI-ST960:105:D10GVACXX:2:1101:5054:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTACTGTA
+TCTCATTAGC
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:5208:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGTTTC
+TCTTGGAACG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:5105:2206 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATGAACTG
+TATTAAACTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5029:2212 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAACATTTC
+GAACAATGAA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:5084:2222 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTACCTCT
+CTCTGACTTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:5223:2223 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCCGGAGTTT
+TTTCAGCAGT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:5173:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATGTGT
+AATGATTCCT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:5208:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTTACTT
+TGATCAGAAA
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5101:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAACTCTA
+CCTTTATTAC
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:5189:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTACAAAA
+CTTTCTAATT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:5018:2248 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATGTAG
+AATATGAGTT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:5160:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTGCTTGA
+TTTTGAAGTT
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:5498:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGCGAGAG
+TTCTTGAACT
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:5435:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATAAGGA
+CTGTGAAGTG
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:5472:2190 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCACTGTAA
+TCTCACGGTG
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:5358:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTAAT
+GTAGTCTTTA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:5420:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCGTTTGAT
+TTGCAAGCTG
+>HWI-ST960:105:D10GVACXX:2:1101:5318:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTTGTAG
+CAAGGCACTG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:5357:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTCATTT
+CTGCTCTTAT
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:5300:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATGTAGA
+ACACACATGA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:5485:2228 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAAATATC
+GTATCCGTTC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:5295:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAAAGACT
+TGGACCTTCT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:5281:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGAGCGTA
+CCGACATGCG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:5679:2172 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAACAATA
+TTCTCATGCA
+CCT
+>HWI-ST960:105:D10GVACXX:2:1101:5663:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTGTAA
+TCTGACTCTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5539:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTGAAAGA
+AAGAGCCATT
+GGT
+>HWI-ST960:105:D10GVACXX:2:1101:5728:2197 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCTGTAT
+AAATAGTTTT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:5500:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTATCAAT
+TGAACTAGAT
+TCA
+>HWI-ST960:105:D10GVACXX:2:1101:5592:2204 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCAATAAAGC
+TGTTGAATGA
+GAT
+>HWI-ST960:105:D10GVACXX:2:1101:5553:2233 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGATCTGTA
+AACTAAAAAA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:5604:2241 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTTGATT
+ACCATAGCAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5743:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGGTTTT
+AAGTTCTTAG
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:5682:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTTGAGT
+ATGTAGAATC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:5979:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTCTCTAG
+AAAATATCAG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:5958:2186 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGCGATGA
+TGATAAAATA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:5985:2215 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATAGTT
+TTGTTGTTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5952:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAGCAGTA
+CAATTGCAGA
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:5970:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTTATGTA
+GTCTCATTTC
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:5909:2233 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCACCAGTTT
+TACAGAGTGT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:5792:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATATAC
+TTCACAACTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:5990:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACGGGAAG
+GTGATATTTG
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:6014:2179 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTACTTCT
+AAGTTTAGTA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6138:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTTATAT
+GAACCAATAA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:6181:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCACAAA
+ATATATAGGA
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:6001:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTGTGAA
+TCTGATTATA
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:6161:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAGTCA
+TAATAATAGT
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:6053:2206 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGTTG
+GCATGAGAAC
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:6128:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATTGTTG
+TACTCTTTAA
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:6082:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTTTGTG
+TGAAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6229:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTTGGTG
+AAGTTTTTAA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:6024:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAAACCT
+ATAATATTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:6181:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCGGCTAA
+TACCTAATGT
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:6060:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGAATCA
+TGTTGCTTTA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:6084:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATGTGTT
+CTCTCTGTTC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6492:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTCACAT
+TATGAATATC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6252:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATATAC
+TTCACAACTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:6273:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATGTTGT
+CTCTCCCTCT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:6457:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGTGAAAC
+TCTATCAATT
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:6377:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGAATATGT
+TGCTGTAGTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6427:2203 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCAAACCAGA
+GACAAATGAC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6279:2218 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCTTGGACTG
+TGAAGTTTGG
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:6366:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGATGTCG
+GCGTTGAATA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6393:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATTGCAG
+TAGAACATAA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:6268:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAACTCTTG
+TGTACCATAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:6467:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATCACCA
+TGTTCCAATT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:6481:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATACTAG
+TGTTTAAGAA
+GTT
+>HWI-ST960:105:D10GVACXX:2:1101:6397:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTAACTTT
+GGCGAATGGA
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:6429:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTATATAT
+GGAGAAAATG
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:6525:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTGTAAG
+CTGAGGAACT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:6517:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGGCAC
+GGCTATGAAA
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:6700:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACATCTCA
+CTGCTCACTA
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:6538:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGCTAGAG
+AGAGGAGGAG
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6575:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTTTAA
+CACCTCTACT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:6501:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTTTATGG
+CTCTAGTACA
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:6631:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTATCTCT
+AAAATTGCAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:6672:2205 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCATGGTTGC
+TTTAATATTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:6579:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCGACTTTG
+ATCCAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6552:2217 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCATCTTTAG
+CTTTATTTAC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:6685:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATTATTA
+TCAATAGCTC
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:6503:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTAGGGG
+CTGATTTGTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:6613:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCTACCAT
+TATGCACTAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:6670:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCGGCGTGA
+AAGGGCGACT
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:6721:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAAACTT
+TCTTAGCTTG
+TCC
+>HWI-ST960:105:D10GVACXX:2:1101:6642:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGGGTGATG
+AACGAAATAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:6589:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTAAAGA
+CAGAGAGATA
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:6684:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGATCGAAA
+CCAAACACCG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:6830:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTGTCAT
+TCTCTAAATA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6954:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATAACT
+CTCTCGCCTT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:6754:2179 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAAGTCG
+TATCTAGGTG
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:6877:2188 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACAAAGT
+CGTTGTAGTA
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:6970:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATCACACT
+GTCAAATCCG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:6918:2197 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTCGGCT
+CTGTTCATAT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:6851:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTTCTGG
+CTGTAGAATC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:6836:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCACGCACA
+CCGCGTGTAG
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:6948:2228 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCCGATAGAG
+AACCTTGCTG
+ACC
+>HWI-ST960:105:D10GVACXX:2:1101:6923:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATTTTA
+TGTGGTGTTA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:6971:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCAGTGA
+TGAAATTATG
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:6883:2236 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGAGTGAG
+ATATAAAATG
+GG
+>HWI-ST960:105:D10GVACXX:2:1101:6822:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGAATTCAG
+ACTGTGAAAC
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:7018:2176 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCGGAGTTTT
+TTCAGCAGTT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:7182:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTGTATT
+TGTGCGTGTA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:7145:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATAATAAG
+ACTCTTAATC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7091:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGTAAT
+GTAGTCTTAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7123:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTCCTTGA
+CTGGAAAAAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:7068:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATGTA
+CCGATGCATA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:7245:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTTACC
+ATGGAACGAA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:7109:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTGTAAT
+TCAGTTAGCT
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:7209:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGTCAA
+TGCATAGACA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:7060:2201 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGTGTGT
+TGGTGGATAT
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:7155:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTGTTGG
+CCTTTAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7198:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATATAT
+TTCGTTTCAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7115:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAGGCT
+GTGGAGGTTA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:7149:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGTTA
+GACTCTTCGA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:7127:2244 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTAGA
+TACTGATATT
+A
+>HWI-ST960:105:D10GVACXX:2:1101:7018:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTTATAT
+GAACCAATAA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:7382:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAGTAGAC
+TTGCAAAGAT
+CGT
+>HWI-ST960:105:D10GVACXX:2:1101:7449:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATACCCC
+GAAAATTAGA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:7359:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGGCTGAT
+TGTAGAATGG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7292:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTCAA
+TCCATGGTTT
+TCTCAAAGTT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:7393:2205 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTCT
+CTGTACTGTA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:7359:2210 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGA
+TCAGAGATCG
+GAAGAGATGG
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:7415:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTAATTA
+TTCGTATGAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:7403:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCGTCTTAC
+CATTTCTTTC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:7373:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGTCTG
+TCTAGTCTAT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:7324:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATCAAAT
+GTATTATATA
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:7309:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTGAGTTT
+TTACATGTTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:7475:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTGACTG
+TATTGAGCAA
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:7649:2170 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTGAGTAGA
+CAATTTAATC
+A
+>HWI-ST960:105:D10GVACXX:2:1101:7708:2170 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGTTTAAT
+AAAACAGAAC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7709:2191 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCTCTCTC
+TTACCTTTCT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:7690:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTCGATT
+AGTACCGTTA
+GTG
+>HWI-ST960:105:D10GVACXX:2:1101:7607:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCCGGAATG
+GTGCCTTTGT
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:7698:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTCTGGCT
+TTGCTCAGAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7518:2217 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAATTCTTT
+TACCGGGTTG
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:7534:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAATGAA
+TGTTTCGGAC
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:7679:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCGGTGA
+GTGGAACTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7747:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCACGAGTC
+GAGGCTCTCA
+ATA
+>HWI-ST960:105:D10GVACXX:2:1101:7610:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCAGTGGT
+AGAGCGCGTG
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:7532:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATGTTC
+ACTGTTCTCT
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:7676:2238 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCCAGCCGTC
+GGATACTGAC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7641:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCTGTAG
+CCTCTCTTTT
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:7966:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGCAACT
+GCAAATTCTG
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:7948:2186 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTGCTGT
+GGATGATCTG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:7864:2190 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGGAAGAAC
+TCTGGAAGTG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7912:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACAAGAT
+GTTTAATCAT
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:7970:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACAATTGT
+TGTCTTGTAG
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:7819:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAATTGT
+TTCTTAGCAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:7762:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTACTTTAT
+AAGGACTGTG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:7847:2207 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGCAACC
+CTGTCTTGCT
+TTA
+>HWI-ST960:105:D10GVACXX:2:1101:7775:2219 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTATTGTG
+TTACTGAATC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:7900:2219 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTACGCC
+CGAACGCAAA
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:7800:2227 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTCTTATGA
+TGTCAAAACT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:7973:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTATGTGT
+TCTGCAGATC
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:7844:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTCGTTG
+GGTTTTCTTC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:7863:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAAATTT
+TCGAAGGAGA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:7912:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGTGTGTAA
+CCTCATATGG
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:7940:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCGTGTCAA
+GTGTAGAATC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8023:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGTATCT
+TGTTGTTTAT
+CTA
+>HWI-ST960:105:D10GVACXX:2:1101:8157:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCAGTGGT
+AGAGCGCGTG
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:8117:2186 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCACTGAATC
+GACTTTGGGC
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:8197:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGGTGCT
+TAAAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8236:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTCG
+GCTTAAACTC
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:8088:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGGAAA
+TGTGCTATGG
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:8085:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCGCAGTC
+GCTAAGCGTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:8003:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATATTTGT
+GGATGATGAA
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:8138:2242 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTATATGA
+TTCTACTTAG
+TCA
+>HWI-ST960:105:D10GVACXX:2:1101:8069:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGGTACTA
+TGAACATTGT
+GAC
+>HWI-ST960:105:D10GVACXX:2:1101:8355:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATGTGT
+AACCCTGTCC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:8375:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TATTGCTATA
+GAGTCACGCA
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:8257:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACCTGGAG
+ACTCATGTGT
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:8438:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTGGTTT
+GGATTTTGGT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:8299:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCTCTGG
+CTGTTGAATA
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:8333:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGCTTGCA
+AGTTCTCTCT
+GAA
+>HWI-ST960:105:D10GVACXX:2:1101:8309:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTGTGTT
+GGCGTTTTAT
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:8363:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCAAGCATG
+ATGAATTGAT
+GAG
+>HWI-ST960:105:D10GVACXX:2:1101:8494:2200 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGCAT
+TGATTGTGGT
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:8291:2212 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTCTACTCT
+ACTAAACCTC
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:8482:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATCTTCCG
+TCTGTTTCTG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:8322:2218 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTTGACCGA
+TGCTCGGACA
+A
+>HWI-ST960:105:D10GVACXX:2:1101:8388:2225 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCGTGTGTAT
+TTAGTAATTC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:8442:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTTTCTA
+TGTTGTTTGG
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:8339:2233 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCATCTCTAG
+AACTCTTTAT
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:8376:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGTGTCA
+GATTCTAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8457:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTCTGTG
+GATTATGCTT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:8627:2171 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGGTAAAT
+TTGTCTGAAT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:8743:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCATCTT
+TTCTTATGTA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8722:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTAG
+AGAAAGTGAT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:8678:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGATGTAT
+ATTTACGAGA
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:8565:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTCCTTC
+GGATCACTCA
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:8583:2192 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAACGCT
+TTTATGTGCT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:8633:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATACATA
+TTGGGTTGTG
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:8687:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTTCTGT
+AGACTATGTG
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:8605:2201 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTTTCTTGT
+CTAGTCGGTT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:8532:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATGAATG
+TGTAGAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8688:2216 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTGGGGAA
+GGATCAGATG
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:8560:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATTGGTG
+CCTGTAGGTC
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:8658:2230 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTGCTATA
+GAATCTGGAC
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:8538:2232 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTTATCT
+TTTACTTTCC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:8669:2248 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTACTGTT
+TTTTCCGCCT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:8917:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATGTTGTT
+GTTGCATGCT
+GTG
+>HWI-ST960:105:D10GVACXX:2:1101:8755:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGATGTC
+GTTGGGTCTT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:8885:2196 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTCCGATGA
+TGATCAAATC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:8967:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTCTTT
+ATTCCTGGGT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:8797:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTAACTC
+TTGCCTCTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:8831:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTGGGT
+TTGTGGTGGG
+GGT
+>HWI-ST960:105:D10GVACXX:2:1101:8957:2220 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTCTTTA
+GCATCGACTG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:8751:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTGTTTG
+TGTTTAAGTG
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:8914:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCGTTTTGG
+CTTTCGTTCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:8937:2229 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTGGAATGA
+TGATAACGAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:8832:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTGTCAG
+TCTAAGAAAA
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:8894:2244 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGAATGTTT
+AAATTGGATC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:8849:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTACTGT
+AGTATATATG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:9130:2168 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGGAATTG
+TTGAGTTTGG
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:9203:2174 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTTGACTGT
+GATTTAAACG
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:9183:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTACTCTA
+TCTTAAACAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:9125:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATCGGAT
+TGTCAAATGT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:9001:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTCTTGT
+TGTCTAACTC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:9175:2204 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGA
+TCTGAGAATA
+AGAACATACA
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:9224:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCGTAAA
+AACTTTGGGA
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:9118:2208 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATAGTTC
+AGTCGACATG
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:9087:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATATGGAT
+GGATAATTTT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:9013:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGGAGCCT
+CTGTAATTTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:9153:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTCTTCGA
+ATGACGAGTT
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:9188:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCCTTTGTCG
+CTAAGATTCG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:9022:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAAATA
+AACACATGTA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:9098:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGAGGAGAG
+CAGTCTATTC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:9115:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGTTTAG
+TTGGCGGTTT
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:9136:2239 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTGCTT
+CCTTTAACAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:9477:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTTATGG
+CACAACATGT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:9421:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCCCAGCCT
+CATAGAGGAA
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:9299:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACCAAACT
+TTTCAAACCA
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:9456:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATTTCGG
+AAATGCTAAT
+CG
+>HWI-ST960:105:D10GVACXX:2:1101:9347:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGCATAATA
+ATGTATTTAT
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:9436:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTATGAG
+TGTGCGTCTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:9384:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTCTGTTA
+CACGCCGAGA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:9328:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTGTTGC
+AGTCGGTGTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:9477:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTGT
+GCTGCTTTCT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:9563:2176 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCCTCGACA
+CTGTTACTCC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:9614:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTGTCAT
+ATTTGCGATG
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:9676:2191 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTAAAT
+CATTGTCTGA
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:9526:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATCTTTT
+GTATTTTGCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:9622:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGTACCT
+GTTATGCTTT
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:9597:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGTAGCTG
+TGGAATGAAA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:9507:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCTAGAG
+CTCTGATGAG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:9613:2210 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTTTTCAT
+AACTCATCCT
+ACT
+>HWI-ST960:105:D10GVACXX:2:1101:9741:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGAGAC
+TGTATCCTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:9572:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATTAAA
+ATTAGAACAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:9606:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTACATATA
+GTAGTGGAGG
+CCT
+>HWI-ST960:105:D10GVACXX:2:1101:9995:2170 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGGGAA
+CTCTTTTGGA
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:9998:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCTTATT
+AGTTTTAACT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:9771:2192 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCCCTATAAA
+TAAAAAACAG
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:9841:2194 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGA
+TCTACACCAA
+ACTCTGGTAC
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:9751:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATTGTTG
+TAGGCTGTGG
+TCC
+>HWI-ST960:105:D10GVACXX:2:1101:9885:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTTTG
+TGTAACTGTA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:9758:2211 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTGGCGA
+CTTTCTACCG
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:9838:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGTAGCT
+CCATGAACAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:9815:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAATAAA
+CACAAAAGTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:9945:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAGGATTG
+GTTTGGTGGA
+TTA
+>HWI-ST960:105:D10GVACXX:2:1101:9878:2215 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGAAGCC
+AGATCAGAAT
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:9912:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAAAGTTA
+ATTTCTGTTT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:9753:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTACCAA
+ATAAGCTTAA
+GTC
+>HWI-ST960:105:D10GVACXX:2:1101:9999:2231 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTTTGTGAT
+ATCTGAAAAA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:9840:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGATTTT
+TCCTTTGTTA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:9928:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGCAAAGG
+CAAGGCTCTG
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:9937:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGTCGGCT
+TAACTAAGGT
+GGA
+>HWI-ST960:105:D10GVACXX:2:1101:9908:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAAGAACTC
+TGTAATTTCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:10129:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGTCCT
+TAATTCATTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:10012:2196 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTGTAT
+CCTTTCTCAT
+TTA
+>HWI-ST960:105:D10GVACXX:2:1101:10236:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATATCACC
+ATGTTCCAAT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:10124:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGTGTTGG
+CATGGGCCTC
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:10018:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCGGTTGA
+CTGGAATTAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10188:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGTGAT
+TGTTGGCAAT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:10113:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAGTGT
+AGAATGCATA
+C
+>HWI-ST960:105:D10GVACXX:2:1101:10363:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGGATTCT
+TCGTTCAGGC
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:10329:2196 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCAAGACTGC
+AACAACTTCT
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:10309:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTTCTGT
+CATCTACATA
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:10373:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGTACTGT
+ATTTGCTATT
+CCC
+>HWI-ST960:105:D10GVACXX:2:1101:10440:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTTTCTT
+TTTGTCGGCA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:10352:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATTATCT
+CTGTTGATTG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:10470:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCCTAGAAC
+TTGCTCAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:10322:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTGGAAC
+TCTTTCTTCT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:10300:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGAATCCAT
+AGTCTTACCA
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:10348:2237 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGACA
+AGTCGAATCT
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:10434:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTATGTCG
+TTTCTTTGAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:10326:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGAGTTG
+ATTGTGCAAA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:10707:2172 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATTTAA
+ATTCCTTCAA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:10553:2176 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGTGTA
+GACTTAATTT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10597:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATGTA
+CCGATGCATA
+GTC
+>HWI-ST960:105:D10GVACXX:2:1101:10566:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAGTTTT
+TGGATTGTAA
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:10694:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTAA
+TGTTAAATAA
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:10746:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTAACAGGG
+ACAGTCGGGG
+GGT
+>HWI-ST960:105:D10GVACXX:2:1101:10522:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTCTGTAC
+AGATATACTT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10609:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTTGGCT
+TTTCTCTGCT
+>HWI-ST960:105:D10GVACXX:2:1101:10672:2216 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGACT
+CGGATACGCT
+TCA
+>HWI-ST960:105:D10GVACXX:2:1101:10584:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGATGTTGA
+GGCTCAAAAG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:10743:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTCGATAG
+AACTACAAAG
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:10653:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGTCCTTC
+GGATCACTCA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:10642:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGATTTTA
+AAGTGTTACA
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:10627:2242 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACAAGTT
+GGTCTGGGTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:10734:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAATCTG
+GGATGAACTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:10579:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATCTTTA
+GTAGAACAAA
+ATC
+>HWI-ST960:105:D10GVACXX:2:1101:10596:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGTACTAA
+TGGCGAAAGA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:10984:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTACGAT
+GTCTCTGTAC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:10870:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATGGGTTC
+GACGTTAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:10979:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACTGAAA
+TGAACCAAAA
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:10780:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGTGG
+AACTACATTA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:10858:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTTGCG
+GATTATGCGT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10924:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACAAAGT
+CGTTGTAGTA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:10881:2211 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCATACTGT
+GTCTGCTTCT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:10798:2212 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCAATGTAGG
+TTGTTTTTGG
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:10962:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATAGGA
+ATCTGTAACT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:10898:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATTTC
+GGCTGTAGCA
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:10771:2225 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGA
+TCGAGAATGA
+TGAACCAATT
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:10861:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTTA
+GACTCTTCGA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10883:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAATGTTC
+TCTTTCTGAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:10793:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAACTAATG
+GATGTATGAA
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:10996:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGTGT
+TGTTGACTCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:10908:2243 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCTGGAATGA
+TGATAACGAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:10822:2244 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTGTGTC
+TCAGAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11150:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTAG
+TAACTGAAAA
+CGG
+>HWI-ST960:105:D10GVACXX:2:1101:11176:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCTGTTGA
+CCAAAAAAAA
+A
+>HWI-ST960:105:D10GVACXX:2:1101:11080:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTCCATAA
+GCTTTGATCA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:11039:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTAGTTAGT
+TGTTTTAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11213:2190 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAATAAGAA
+TAAGAATAAG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:11039:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGAGAAAA
+TGAGCATTAT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:11145:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTTGT
+CTCTTAATCG
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:11168:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATCAATG
+CTGGTGCTAA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:11088:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAAGAACAA
+GAACACATTT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:11184:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACATCCTT
+TCAAAACAAG
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:11073:2233 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAAGTCT
+GGAATAGCTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:11102:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTTGTCG
+AACTTGTAAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:11129:2239 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGGTTGGTT
+ATACACCAAA
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:11163:2245 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAATAT
+GTCTGGCTTG
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:11321:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAATCTGT
+TTGGTTGTGG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11427:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTCTTGG
+TAAAGGTTGA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:11305:2204 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTA
+TCTACTGACC
+CCGAGGCTTT
+CGC
+>HWI-ST960:105:D10GVACXX:2:1101:11259:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATATGTT
+TCGTAGAACT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:11401:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTAGAAA
+ATGAACTATA
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:11352:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTGAATA
+GTCGGGGTTA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:11437:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTGCGTC
+GTATGAGTAA
+AAG
+>HWI-ST960:105:D10GVACXX:2:1101:11258:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAACCGAGT
+ACTTTTGGTA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:11443:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGTAGT
+GTAGTGGTAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11272:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGTGCTTC
+AACGGCTCTG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:11399:2247 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCATATGAAC
+TACGTGTGGC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:11611:2171 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGGAGCTC
+AAGAACGGAA
+GAT
+>HWI-ST960:105:D10GVACXX:2:1101:11736:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGAATACTG
+TGGTTGTTTT
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:11736:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGATACAA
+TTTCGGTTTC
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:11623:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGTTTTG
+GGGTTTTAAA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:11724:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTAGGAC
+AGTTCATGTT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:11676:2225 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGCATCAA
+GCTGTAACCG
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:11707:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGGTATGAA
+CTATGAACAC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11640:2237 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTTA
+GACTCTTCGA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:11532:2244 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTAGTAA
+TAGAGCTTGG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11511:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTGGAGA
+TATTGGTTAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:11573:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAACAATTC
+GGCTAGAAAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:11773:2169 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTTTCTTAC
+TTCGGCCTGT
+T
+>HWI-ST960:105:D10GVACXX:2:1101:11943:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGATCAT
+ATGGACGTAA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:11759:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTGAGCT
+CTTCTTTTCT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:11857:2196 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCTGTAG
+TAGGCTTGCA
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:11838:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATCAATG
+TATTGTATCC
+G
+>HWI-ST960:105:D10GVACXX:2:1101:11790:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGAATTTC
+TGTAGACTAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:11770:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGATGCGA
+TCATACCAGC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:11869:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGATGTT
+GGTTTGTAAT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:11959:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTACTGTA
+CACACAAACT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:11892:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATAAAAT
+GACTCTGAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:11899:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATAATGT
+AATAGTACTC
+ACC
+>HWI-ST960:105:D10GVACXX:2:1101:12088:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTTTGTA
+CAAATCCAAA
+CCT
+>HWI-ST960:105:D10GVACXX:2:1101:12143:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTCTGTC
+AACCTCTTCG
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:12198:2193 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAGGGATGA
+TGATTCAATT
+A
+>HWI-ST960:105:D10GVACXX:2:1101:12019:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATTGTTG
+AACTTAGAAT
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:12174:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTCTGTAG
+CTCTAGACCA
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:12126:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATTCCCG
+TTGAGAGGAT
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:12157:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGCTACTC
+TCCTCGTCTC
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:12048:2210 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTACCACTC
+TTGCATTTGC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:12070:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACAGAGCT
+CTGATTAAAG
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:12006:2219 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAGTTGA
+GCGGTTGAAT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:12122:2230 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTCTGTAT
+GCTTTTTTGG
+GAC
+>HWI-ST960:105:D10GVACXX:2:1101:12107:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCACAAC
+CTGTGAAAAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:12066:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTGTGGAT
+GATGAAGAGT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:12166:2250 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGCAATA
+TTCTAAAGAA
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:12124:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGAATTTGG
+ATTTGATCAG
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:12436:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATAAAGT
+TAGTTGGTGG
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:12303:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATCTTTCT
+ACTTTCATTA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:12490:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTTCAATT
+ATGAGTTTTC
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:12308:2196 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTATAGTTA
+AAAGAGCACT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:12371:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGGTTTGG
+ACAAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:12329:2218 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCCTTTGTCG
+CTAAGATTCG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:12376:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGATCAA
+GTACAAGGGT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:12362:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATATC
+GCATTAGCCC
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:12430:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAATATA
+CACTGAACTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:12484:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAAGTTT
+CTATCAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:12259:2237 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGCCTTGCT
+CTTCATTGGT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:12345:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCCCGATAA
+ATAGAACGAT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:12290:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGTCTG
+AAAAAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:12617:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAGTCT
+TATTGTATCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:12673:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGATTCA
+AATCGATCCC
+T
+>HWI-ST960:105:D10GVACXX:2:1101:12575:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTATAT
+TATGTGAAGT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:12730:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGAGTCG
+ATCGTAGAGT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:12674:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGTTT
+GATGTCTATG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:12690:2226 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCACTAGCT
+TCTACTTTGA
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:12653:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTGTTTC
+TGTCTATGAC
+TCC
+>HWI-ST960:105:D10GVACXX:2:1101:12702:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGAGCCTT
+GTTTCTTATT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:12587:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTATTGA
+TGATTCTATC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:12614:2244 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCGACATT
+TGGTGTGAAA
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:12849:2171 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGCCCGACC
+TCGGACTGGG
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:12894:2184 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAAAGTAGT
+CTCATCTTAT
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:12816:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTAAAGG
+CTTATTATCA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:12946:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTGATGA
+AATCTCATAT
+TGA
+>HWI-ST960:105:D10GVACXX:2:1101:12964:2189 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTAATATAT
+GGACAATTTG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:12914:2190 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTAA
+CAACTTTTCA
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:12899:2205 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGAAAGT
+AGCATCAAAA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:12750:2211 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATCTAGTA
+CATACTCTGT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:12962:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTTTGTC
+TGAGTACGAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:12876:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATAATT
+TTTAGTGAAT
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:12908:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTATGAT
+GTAGAAGTAT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:12760:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGGCT
+CTTGTTGTGA
+ATC
+>HWI-ST960:105:D10GVACXX:2:1101:12926:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATTCAG
+CAGGATTATG
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:12942:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATTTCAT
+TGTCTTGTCG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:12902:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTATTTA
+CATGTTGTTT
+GG
+>HWI-ST960:105:D10GVACXX:2:1101:13052:2176 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTTGTGA
+CTGATCATTA
+G
+>HWI-ST960:105:D10GVACXX:2:1101:13197:2180 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTTGTCA
+CATTGTAAAT
+CCC
+>HWI-ST960:105:D10GVACXX:2:1101:13235:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTAATAAG
+ATTTTCTAGT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:13099:2185 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TTCTCTGTAT
+CTCTCGACTC
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:13082:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTAGTATTA
+TTATACACAC
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:13132:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATAAAT
+AAGCTTTGTT
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:13120:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATTTG
+GACTGAGTCT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13177:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTACGTC
+GTTTTGTTCT
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:13060:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATTAAAG
+AAGAACCCAA
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:13106:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCGTAAAC
+TCATAAATAA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13215:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTGTGTT
+GGCGTTTTAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:13012:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAATGCCC
+ATTAATCGTG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13172:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTGCCTAT
+TTATTTGCTG
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:13045:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTCTGAG
+ATTGTAGAAC
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:13155:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAAAAGGT
+CAAGGTTGGC
+AAG
+>HWI-ST960:105:D10GVACXX:2:1101:13458:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGTAAT
+GTAGTCTTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13473:2178 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGTTAGGAC
+AGTTC
+>HWI-ST960:105:D10GVACXX:2:1101:13435:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGAATAAT
+GAACTTTGAT
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:13272:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAAATCT
+CCCTTTTTTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13312:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTGTGTAG
+AATCTGCTTA
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:13253:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TAGTTTGGAC
+GTTGGTACAC
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:13363:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGCTAAGG
+AAGTAAAAGC
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:13404:2208 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACGACATT
+GCATTGTATG
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:13366:2209 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATATGTT
+GTCGGTTCTA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13340:2212 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATATGTT
+TCGTAGAACT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13430:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGTTTT
+GGATACATAA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:13478:2222 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATGGTGAT
+GAAACGAATA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:13253:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATGGGTC
+TCTAGATGCT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:13357:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTCTTTG
+GTGCCCATGC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13444:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTTACGA
+TTCATGGTTC
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:13383:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAATCTC
+TACTGTTTGT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:13323:2243 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTCTCAA
+TACTTTCTTC
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:13556:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTTGTAT
+AAACGGAATT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:13647:2177 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCTTGATCA
+CGAACATAAT
+ATT
+>HWI-ST960:105:D10GVACXX:2:1101:13575:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGCTTGCA
+AGTTCTCTCT
+GAA
+>HWI-ST960:105:D10GVACXX:2:1101:13528:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAGTATG
+TTTGCGGATT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13614:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTCTTTC
+GAGTTTTATG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13510:2190 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTGTCTTT
+CTCCTTCTCT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:13692:2200 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGCTTTG
+CTTAATTCAT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:13666:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCAAATTT
+CAATGAGATT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13720:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATCAGAGT
+GACTCAACCA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13526:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGCCCTTT
+GTCGCTAAGA
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:13506:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATAATGT
+GTGTGGGACT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:13623:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATGGCAA
+TCGTCTCTCT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13684:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGGTC
+CCCACTGAGA
+ACT
+>HWI-ST960:105:D10GVACXX:2:1101:13646:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTGTTA
+TAGATTCCTC
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:13506:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGGAACAA
+GGATTACAAG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13700:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATAAGCT
+GAGCGAATAT
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:13525:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTGTTATT
+GGCCCAAGTA
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:13744:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATGCTCT
+TTTAATGTGC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:13514:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTTTCAA
+ACTGAGCAAA
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:13631:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGTTAATG
+TCTCTGAAAC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13611:2250 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAACGTAGA
+AACTCTTGGT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13873:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGGGGTCC
+CAGTTCCGAA
+CCC
+>HWI-ST960:105:D10GVACXX:2:1101:13832:2175 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTGC
+CTTTTTCTCT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:13756:2181 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGA
+TCACAGTCGG
+CTTACCCGGG
+GAC
+>HWI-ST960:105:D10GVACXX:2:1101:13888:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGAGAGA
+TTTCGTAAAA
+AAC
+>HWI-ST960:105:D10GVACXX:2:1101:13863:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTGGTTG
+GTGTAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:13978:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGACTC
+TGTAGCTTTA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:13770:2198 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCAACATAT
+GTTTCATAAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:13874:2204 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATAAAAGT
+TGTCGTAGCA
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:13985:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTCTTGAC
+TTGCCTCCTT
+ACC
+>HWI-ST960:105:D10GVACXX:2:1101:13941:2214 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCTATTTATA
+TATTTGATGT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:13963:2214 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTCTGTCT
+ATTTCGTTAA
+ATC
+>HWI-ST960:105:D10GVACXX:2:1101:13752:2222 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTTTGTCAA
+TTGTCATATT
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:13859:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTCTGTTT
+CAATGTCCCT
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:13939:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAGAGTCAA
+GACTCAAGAC
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:14180:2173 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCACAACAG
+CATATTTATA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:14103:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAACAAAAG
+TGGCTGTAGT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14196:2181 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAGGTGT
+TACTGTGGAT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:14128:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATGTA
+GTAGCAACTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14033:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTGGTAA
+CTGGACTCTG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:14074:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTAATACA
+CTTTCCCTTA
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:14019:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTCTCTGT
+GATTCTCTTT
+TTA
+>HWI-ST960:105:D10GVACXX:2:1101:14232:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAGCTGGA
+AACTTTGAGC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14143:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTGG
+CACACTAAGC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:14121:2210 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTAGTAG
+CATGTGAATT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:14168:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATTCTAT
+CGGATTCTCA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:14102:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTATTTG
+ATCTACATTG
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:14036:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCCCGAAC
+TCTACGTAGA
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:14209:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTACTCAA
+CACTCTCTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14087:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGAGTTCT
+TAGCCATTGC
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:14127:2230 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCACTCTGGA
+TTCAATTTGG
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:14472:2172 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATAACGA
+TCCTCTGTGT
+CTCTCTCGAT
+CGA
+>HWI-ST960:105:D10GVACXX:2:1101:14402:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATAAAGT
+GGTCTAGTGG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14443:2185 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTTTTACTG
+TCCTCTGATC
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:14420:2208 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATGTAT
+ATATAAGAGT
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:14467:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGAAACTG
+TACTTGAGAT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:14311:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTCTTTAT
+GGCTCTAGTA
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:14442:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAAAATGT
+CGTTGTAGTA
+TAG
+>HWI-ST960:105:D10GVACXX:2:1101:14388:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATTCCAG
+TTGATTGAGG
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:14404:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTGTTG
+GCTATGATGT
+TAT
+>HWI-ST960:105:D10GVACXX:2:1101:14361:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAAATTATG
+ATGGAAGATT
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:14303:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACATTTAG
+GCTCAGTGGG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:14342:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGCTCTTCA
+ACCTTAGAAG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:14263:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTACTTTC
+TCGTGCTAAC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:14512:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGCAATCCC
+TCTGTTTCCT
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:14677:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGACAGA
+AGATAGAGAG
+CAC
+>HWI-ST960:105:D10GVACXX:2:1101:14738:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATGTTCA
+TGTCTAAATT
+CG
+>HWI-ST960:105:D10GVACXX:2:1101:14684:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAGCCGGA
+GACAGGAGAG
+GTG
+>HWI-ST960:105:D10GVACXX:2:1101:14526:2204 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCACATAGAC
+TAATCTTATA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:14580:2206 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAATAAGG
+TATCAGGTTT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:14592:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTTATAGG
+GAGAAGAAGA
+GGC
+>HWI-ST960:105:D10GVACXX:2:1101:14659:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATTGGTG
+CCTGTAGGTC
+AG
+>HWI-ST960:105:D10GVACXX:2:1101:14548:2237 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCAATTTTAT
+GTCGTTTCTT
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:14962:2168 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATCCACA
+CTAAGTCCAA
+GC
+>HWI-ST960:105:D10GVACXX:2:1101:14851:2171 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTATTTGTA
+GCAATTCTGT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:14982:2172 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCGTAATCTG
+GGATGAACTC
+ACT
+>HWI-ST960:105:D10GVACXX:2:1101:14927:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTCTTGT
+TTAGAAGCAA
+GAA
+>HWI-ST960:105:D10GVACXX:2:1101:14906:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGCCAACTC
+TGTTTCTTCT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:14858:2195 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCA
+TCATTCGTTT
+CAATGTCAAT
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:14936:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGCCAATG
+TTGTAGAACT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:14780:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTGTGAA
+TCCTTTTCCA
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:14808:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATGAAGA
+GGCTGTTTCT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:14828:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGTATGT
+TGTTATTTGA
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:14929:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAACACTCT
+TATCAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:14844:2223 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCATACATCT
+TTGCAGAACT
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:14988:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGCTTAGA
+CTTGGTAGTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:14821:2236 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGTGTACT
+TGTGGACAAG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:14761:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTTGTAG
+TCGTAAATAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:15030:2168 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTCTGTTA
+CACGCCGAGA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:15079:2180 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCAGGGCA
+AGCACAACAT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:15143:2186 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCATCTTTTT
+CATCCCAATC
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:15178:2193 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAGTGATGA
+ACCTTTTGAA
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:15053:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATCCAGT
+CTCATCGCTG
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:15025:2214 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGA
+TCGTATGTAA
+AGGTTTACTC
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:15186:2216 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCAGAGCAAG
+TCGAAATCTG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:15065:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTGTGCTG
+GGAACTATTT
+GAC
+>HWI-ST960:105:D10GVACXX:2:1101:15143:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATGAAAAC
+TTCTTGAGTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:15008:2227 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCTTTCTTGG
+GACTTGATTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:15207:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTAGTGT
+GTAATGTTAT
+TGG
+>HWI-ST960:105:D10GVACXX:2:1101:15000:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTGGTCA
+TGTTTGCTAT
+TTG
+>HWI-ST960:105:D10GVACXX:2:1101:15274:2198 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCATCTGTC
+TAAAGTTTGT
+TCT
+>HWI-ST960:105:D10GVACXX:2:1101:15308:2216 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAGTAATTT
+AGCATGTTGC
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:15475:2222 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCTGTAG
+TTGTATTTCA
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:15291:2232 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGTTG
+TTAGCTATCA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:15347:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGAACTCT
+GACCAATGAA
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:15331:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTGTTATA
+TATTACTGAC
+TAC
+>HWI-ST960:105:D10GVACXX:2:1101:15450:2248 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGTTTTGT
+CCCTTTGTAT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:15691:2179 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTACTAGTC
+TCGTATTAAC
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:15591:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTTGCTT
+ATGTGCCCGT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:15612:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATATCCTA
+TGTCTAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:15528:2190 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATTTCGGA
+TCTTGGCTAC
+TAA
+>HWI-ST960:105:D10GVACXX:2:1101:15503:2198 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAATCTAAA
+GGGATTTGGT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:15541:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CAAACTTGAA
+TCGTCTGTAG
+CTCTAGACCA
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:15700:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTAAATTC
+TCTTCCTTTG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:15649:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTAATGTGA
+TGGTTTCTTC
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:15573:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATAGCTA
+GTCATAACTC
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:15731:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATATGTT
+TCGTAGAACT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:15639:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTTTTACG
+GAGTACAAGA
+GAT
+>HWI-ST960:105:D10GVACXX:2:1101:15824:2174 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATATGTC
+TGTACACAAT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:15924:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGAAA
+ATGTTGTGAA
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:15857:2189 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTAGGTT
+TAGAGCTAAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:15755:2216 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATACTA
+CTAATACATT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:15970:2220 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCCATGACTG
+AAGTTGTTTG
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:15886:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGTTTT
+ATTTCTTATT
+CAA
+>HWI-ST960:105:D10GVACXX:2:1101:15866:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGTGTTG
+GCGTTTTATC
+TG
+>HWI-ST960:105:D10GVACXX:2:1101:15925:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTTTTGTT
+GGATTGTTTT
+GCT
+>HWI-ST960:105:D10GVACXX:2:1101:15938:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTCTTGTCC
+GTTACATTTG
+CC
+>HWI-ST960:105:D10GVACXX:2:1101:16016:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTGTGTT
+GGCGTTTTAT
+CTG
+>HWI-ST960:105:D10GVACXX:2:1101:16084:2189 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAAATGTGA
+AATCTTAAAA
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16060:2193 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCGAGAATGA
+TGAACCAATT
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:16022:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCATGAGAT
+ACTGAATTCA
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:16131:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTATGTAT
+GATCATATTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:16147:2216 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCATTCAAAT
+CAGAGGCTTG
+TTA
+>HWI-ST960:105:D10GVACXX:2:1101:16171:2218 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTCTTCTTC
+GTTTGGCTAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:16114:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGCAGCAC
+TTGTCTGACC
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:16083:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATGTAGA
+GAATCGATTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:16174:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCACTTTGAG
+AACTAAAAAA
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:16002:2242 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGGAGTTT
+TGGTTAGGTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:16214:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTGGTAG
+ATGATAACAA
+ATC
+>HWI-ST960:105:D10GVACXX:2:1101:16126:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTGTTGT
+TGTTGTTGTT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:16191:2247 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCTGGAGAAC
+TTGGCAACTC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:16438:2169 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATGTTCGG
+TTGTGGGATT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:16355:2177 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTTA
+GACTCTTCGA
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:16306:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTACCTACT
+CGTCGTACAT
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:16427:2183 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGTTGATTT
+TAATGGTTAC
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:16368:2191 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATAAAAAC
+TCTGAATTTA
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:16496:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTTCTGTTG
+AACCTCTTG
+>HWI-ST960:105:D10GVACXX:2:1101:16268:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTCAAACC
+ATTGAGACAG
+CTT
+>HWI-ST960:105:D10GVACXX:2:1101:16478:2197 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCCTGTGAAA
+CTGCGAATGG
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:16378:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTACGTTA
+TTTAAAATCC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16273:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTTATGT
+GACTGGAGAG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:16350:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTGTGGCT
+CAGAACCACC
+AC
+>HWI-ST960:105:D10GVACXX:2:1101:16328:2230 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAA
+TCACTGATCG
+CGTCGTGTTA
+C
+>HWI-ST960:105:D10GVACXX:2:1101:16408:2232 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTCGAAC
+AATGAACAAT
+TGC
+>HWI-ST960:105:D10GVACXX:2:1101:16369:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTACATTGT
+GAAATGATAT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:16305:2250 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCAAACCTG
+TATCTGTGTA
+ACT
+>HWI-ST960:105:D10GVACXX:2:1101:16647:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTAATTGAA
+TATCTTCAAT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:16734:2178 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTACGAAT
+TCTAAATTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:16682:2192 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTATCAATA
+AGCGGAGGAA
+AAG
+>HWI-ST960:105:D10GVACXX:2:1101:16516:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGAGAGTTC
+GAATCTGTCA
+GGC
+>HWI-ST960:105:D10GVACXX:2:1101:16583:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATCGGCGC
+TTGTTCACCT
+CTC
+>HWI-ST960:105:D10GVACXX:2:1101:16633:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCATTGTATT
+TTAACAGCAC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16696:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTAAT
+GTAGTCTTTT
+AT
+>HWI-ST960:105:D10GVACXX:2:1101:16666:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTAACAC
+TTGGTTCCGT
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:16730:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCCTATAAA
+TCGTCTCATG
+AA
+>HWI-ST960:105:D10GVACXX:2:1101:16561:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATAACCCT
+TTCCAGGCCA
+TGT
+>HWI-ST960:105:D10GVACXX:2:1101:16708:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCACCATTG
+TCTGAATAAA
+AAG
+>HWI-ST960:105:D10GVACXX:2:1101:16847:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCGATGTCGG
+CTCTTCCTAT
+CAT
+>HWI-ST960:105:D10GVACXX:2:1101:16809:2177 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACATCCTC
+ATAATCACTT
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16946:2180 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTCTTTTG
+TCGGCGTTAG
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:16831:2183 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTATGTTAT
+GGATTCAAAA
+AAA
+>HWI-ST960:105:D10GVACXX:2:1101:16770:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTCAGCCCT
+TTGTCGCTAA
+GA
+>HWI-ST960:105:D10GVACXX:2:1101:16858:2188 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAATTTTTA
+GTGACCCTTT
+TA
+>HWI-ST960:105:D10GVACXX:2:1101:16876:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATGTTC
+TCTGTTATTC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16983:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCCTTTGTGG
+GTTGAGTTGT
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:16842:2205 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTATGAAA
+TCGACCATGA
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:16962:2210 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTCATGCT
+GTTTTCCAAC
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:16751:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTACTGTT
+TTCTGTTTTC
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:16898:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCAACCCCCG
+AACTATATCC
+TC
+>HWI-ST960:105:D10GVACXX:2:1101:16969:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCATTATCTT
+GTAGAATGTT
+CA
+>HWI-ST960:105:D10GVACXX:2:1101:16781:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTTCTCCT
+CTCGTCCATA
+AAT
+>HWI-ST960:105:D10GVACXX:2:1101:17222:2169 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTGGATCCT
+GTTTTGGATT
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:17028:2180 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATA
+TCCTATTTAC
+TATTTGAAAA
+AGC
+>HWI-ST960:105:D10GVACXX:2:1101:17127:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCAATTGGAC
+TGTTTAACGT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:17143:2189 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCAAATTTCT
+ATATATTGTT
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:17161:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCTTCTGGAC
+ATTAGCCATT
+AGT
+>HWI-ST960:105:D10GVACXX:2:1101:17133:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCTGCCTTTT
+CCTTCTTGTC
+GG
+>HWI-ST960:105:D10GVACXX:2:1101:17121:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGGCACTTC
+TGTTCTGATC
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:17033:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCACTAGACA
+AACTCTCAAG
+A
+>HWI-ST960:105:D10GVACXX:2:1101:17178:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGTTTGTAG
+TCATAATTTA
+GT
+>HWI-ST960:105:D10GVACXX:2:1101:17141:2241 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGA
+TCGTATGTTT
+CACTCTGTAA
+CT
+>HWI-ST960:105:D10GVACXX:2:1101:17119:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCGAGACCAG
+ATGTGCGATG
+TTT
+>HWI-ST960:105:D10GVACXX:2:1101:17246:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAA
+TCATTTGGTT
+AGGTCCTTTG
+TTC
+>HWI-ST960:105:D10GVACXX:2:1101:17011:2248 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTTTTGAGG
+TTTTAAGATG
+TT
+>HWI-ST960:105:D10GVACXX:2:1101:17469:2169 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCA
+TCTGTGTTGG
+TGAAGGAAGG
+AAC
diff --git a/src/libqes/test/data/test.fastq b/src/libqes/test/data/test.fastq
new file mode 100644
index 0000000..c66fd84
--- /dev/null
+++ b/src/libqes/test/data/test.fastq
@@ -0,0 +1,4000 @@
+ at HWI-ST960:105:D10GVACXX:2:1101:1151:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGACATTGAATCTATATGT
++
+JJJJJJJIJHIJCC#4ADFFHHHGHJJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1205:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGNATTCTTCTTTTGGAACTC
++
+JIJIJJJJJIIIBC#4ADDDHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1122:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCAGTTTAAAGTTAACTCATTG
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1229:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTGAGTTTTTGGACTGTACAT
++
+IJJJJJJJJJJJCCCFFDFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1175:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAATTGTCACTGTTTCACCC
++
+IJJHHIJJJJJJCB at FFFFFHHHHHJJJJJIGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1175:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGTGACTCTGTTCCTGTTGT
++
+IJJJJJJJJJJJ at BCFFFFFHHHHHIJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1204:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCACAGAGCAGCAGTATTTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1237:2239 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTACACACGTATATGCAATAC
++
+IJJJJJJJJJJICCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1123:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATAATGTGGTATTAGTCTG
++
+JJJIJJJJIJJJBCCFFFFFHHFHHJIJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1155:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGCCACTGAACTAAAAAAAAA
++
+HFFFFFEEEEEECCCFFFFFHGHHGJJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1466:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGNAAACGCATGTAGATGAT
++
+JJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1443:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTACCAAAGTCTGAATGATTAT
++
+IJJJJJJJJJJJCCCFFFFFHHHHGJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1360:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCCGGCTCTGTCTCTCTCTCCC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1272:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCATTTAGAGGAAGGAGAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1423:2185 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGACGTCAAATTATGCCT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1398:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAAAAAAAAAAGAATAAAGAA
++
+C at CBBAABCCCC@@@DDDDDHHFDFIBFHG<FH
+ at HWI-ST960:105:D10GVACXX:2:1101:1333:2199 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATTACAAAGTTTACATCTCT
++
+JJJJJJJJJIJJCCCFFFFFHHHHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1388:2214 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTCGTCTTCCATTTCTATTT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1366:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTATATGCTGTGGTAG
++
+JIIJJJJJJJIJCBCFFFFFHHHHHJIIJFFG
+ at HWI-ST960:105:D10GVACXX:2:1101:1297:2232 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATTCATGTTGATATATTTAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1374:2245 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTGTGTGTCTGAAGTAGTTGA
++
+IIIIGIIJJJJJ@@CFDDFFHHHHFJGIIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1277:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGTTTCAGACTTCGAGAAGC
++
+JJJJJJJJJGIHCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1425:2250 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATATACTTCACAACTCTG
++
+JJJJIIJJJJJJCCCFFFFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1714:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTNGTATGAACTCTGGTTTA
++
+JJJJJJJJHJJJ@@#4ADDFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1601:2174 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTTTTACGTAGACGATGTGCC
++
+IGJJJJJCDHGICCCFFFFFHHHHHIJIIGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1581:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCAGTTGAGGAACTATTGTTTC
++
+HIJJIIIJIIIJCCCFDFFFHHHHHJJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:1717:2186 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAATCTTTGTACTGTTGAACAA
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1538:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACTGTTTGTGTCAATCATT
++
+JHJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1687:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGTCCTTCGGATCACTCAA
++
+IGIIJJJJJJJJCCBFFFFFHHHHGJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1589:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGAGCACAAAGATGATCAAAC
++
+JJJJJJJIJJJJCCCFFFFFHHGHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1611:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGAGAGTAGCTCTGTTTAT
++
+IJJJJJJJJJIJCCCFFFFEHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1672:2207 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATATTTGATACATCGGTTC
++
+IIJJJJJIJJJJCCCFFFFFGHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1595:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTCTGACTGATGAACATATTT
++
+IDHIIJJIJEIGCCCFFFFFGFHGFHIIIGIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1706:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTGCAATTAGTGCAACTGA
++
+JJJJJJJJJJJJCCBDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1575:2228 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGTTTGAGACTCTATCTTACCT
++
+JJJJJJJJJJJJ at CCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1557:2229 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTTTTGTGTGTACTTGTCC
++
+IGIJIGIJGGGH at CCFFFFDHDHHHJIJGHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1747:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATATACAATTGTGGACTAC
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1835:2159 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNAGTTTCTTCTTCATTGT
++
+JHJJJJJJJJJJ at B#4ADDFHHHHHJJJJJIG
+ at HWI-ST960:105:D10GVACXX:2:1101:1976:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACNAGGTCGAATCGAAATGT
++
+HAHIIJJIJJIH@@#4ADADDHHHHIIJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:1781:2164 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNTGTGTTGTTGACTCTGT
++
+JJJJJJJJIJJJCB#4ADDDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1903:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNATCAGAGACTAAAGTAGT
++
+IJJJJJJJJJJJ at C#4ADDDHFDHHJGIGEIGH
+ at HWI-ST960:105:D10GVACXX:2:1101:1854:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNATATCCTACTACAATGC
++
+IIIFBGDGCGII@@#4ADD=FHDHHGIGIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:1756:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNTGGTCGATATGTCTTTT
++
+HGJJJJJJJHHHBC#4ADDFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1921:2172 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTTAGAACTCTTTTCCTA
++
+FHIIB8CHGIII@@<DDD?DH??FFEDHGC@@
+ at HWI-ST960:105:D10GVACXX:2:1101:1992:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTGTTGGGGTAAAAAAAAA
++
+@@CE@?BCACDCBCCFFFFFHH at FHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1925:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAAGTGTGATTCTTTTGG
++
+GDHIEHJJGEGH@@BFFBDEHHHGHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1792:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAAAGTCATGTCTTTGTTGT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1771:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGTGACCGAGAAATGTTTAA
++
+IIIIIIIIIIFF@?@DDDDD?CCF:EGG at G@D
+ at HWI-ST960:105:D10GVACXX:2:1101:1915:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTCAGTCTAACTAAAGTATT
++
+IJJIJJJJJJJJ@@BFFDEFHHHHHJJJFHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:1899:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCACTAATACAATTGTTGCTC
++
+JJJJJJJJJJJJ at CCFFFFFHHHHHGHGHHII
+ at HWI-ST960:105:D10GVACXX:2:1101:2023:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTANAATTGTGTGTAAAGTAA
++
+IJJJJIJJJJJJ@@#4ADDFHHHHFHIIJHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2059:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTANTGGGAACATAAATGAAGG
++
+FCFAEFHGCEAC@@#4ABBDHDHFFFHIGIIIH
+ at HWI-ST960:105:D10GVACXX:2:1101:2077:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNGGTTCCGAGGCCCTCTC
++
+@=CAHHEFFFFC@@#4AABDHHFHFIGIIGIG
+ at HWI-ST960:105:D10GVACXX:2:1101:2182:2164 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTANCTTCTCTGTTATGTCTC
++
+JJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2049:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTCTTGTACTACAGTGAT
++
+HGIFGGCDFGIH:??DBDDBFBFDHGIEADCI
+ at HWI-ST960:105:D10GVACXX:2:1101:2035:2185 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGTAGAATTCAGAATGTCT
++
+IIJJJIJJJJJJCCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2214:2203 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTGTACACGGCTTAATTTATT
++
+JJJJIJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2244:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCGGTTTGAGTGTTGCAAATCT
++
+==BCC at C@D at 77??<A?D?BC2<DDCEEEE at BF
+ at HWI-ST960:105:D10GVACXX:2:1101:2185:2223 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAACAAGGTCGTTGTAGTATAG
++
+IJJJJJJJJJJJCCCFFFFDHHHHHJJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2067:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTCCATAGATTGTAGCCTC
++
+IGIJJJJJJJJJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2032:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTGTTAGTTACGCTTTGC
++
+JIIIJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2011:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAATATGATATGAAAATCT
++
+JJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2444:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTCCTGTGATTTGCAATTTC
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2254:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCCATAAAAAGTCTCTACAAT
++
+JJJJJJJJJJJJCCCFFFFFHHFHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2448:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGAAGAAAAAGATGACCAGCT
++
+HIJJJIIJJJJJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2342:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATGTTCGACTGTGAACCTTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2268:2215 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCAATATCAGAACTCGTTATATT
++
+IJJJJJIIJJJJBBCFFFFFCDFFHJHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2411:2223 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGCAACTGTAGCAAGAAGAAAC
++
+GIJJJJJGIJJICCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2292:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTACTTAAAGAGCCCTAAC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2448:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATGAGTGTAGGCTTACTTAC
++
+HIJJJJJJJJJICCCFFEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2389:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCGATCTGGTTTGTAGAAC
++
+IIJJJIJJJJJJCCCFFFFFHHHHHJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2607:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNAACCTGTAGTAATGAAG
++
+IJJJJJJJJJJJCC#4ADFFHHHHFHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2633:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGNATGAACTCATGAACTTTT
++
+HIJJJJJJJJJHCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2513:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTANGTAATGTAGTCTTTTAT
++
+JJJIIJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2675:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAAGTGAACTCTGTGCGTCT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2548:2190 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATCTTCTGTTGACTCATGT
++
+JIJIHJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2610:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAGTATCAATTGAACTTTT
++
+IJJJJJJJJJJJCBCFFDFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2657:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATATATATATAAATGCAGAC
++
+FHJJJIJJJJJJCCCFFFFFHHHHHJJIIJIII
+ at HWI-ST960:105:D10GVACXX:2:1101:2576:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATATTTTTCCCACTGTGTTCT
++
+HIJJJJIJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2626:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGAGAACTCTAGAAACCTGCTT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2660:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTACAATGTACTGGAAACTT
++
+JJJIJHEEGIII@@@FFFFEFFDDDFGHGHIGI
+ at HWI-ST960:105:D10GVACXX:2:1101:2509:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCAAACTTTATGTAAACTCT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2536:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATACCAAATAGAATTTCTG
++
+HIJIGHEGGIGACCCFFFFFHHHHFFHGJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:2584:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGTGCCTGGATTAATATGA
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2674:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGCAACTGCAAATTCTGCA
++
+IIIJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2718:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACGGAACCAGTGACCGTCGT
++
+IIJHHGHHHHHFCCCFFFFDHHHHHJIEIIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2630:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTACTTGAACAGGATCTGTT
++
+?FGBGECHEHE9111442=BFFHHHHGEADDA
+ at HWI-ST960:105:D10GVACXX:2:1101:2808:2165 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACNTGTGATTGTAGTCATGT
++
+IHJIJJJJJJJJCC#4ADDFHHHHHJIIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:2922:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTNACTGGCGGCGAGAATAT
++
+DDDDDDDDDDDDBC#4ADDFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2869:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTCCGATGATGATCAAATCAT
++
+HJJJJIJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2917:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGTCTCGCTTATGACTATGA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2789:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATATTGGTCTGTATTGTGCTC
++
+FGIIJGIIIIJIC at CFFFFDHHHHHHIJHIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:2841:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAGAACTAACAGATATATGT
++
+IEIJJJJJJJIJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3131:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNGACTTAACAAGTTGGTCT
++
+IJJJJJJJJJIJCC#4ADFFHHHHHJHIJJGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3006:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNTTCAGCTACATGCTGAC
++
+IJJIJJJJJJJJCB#4ADFFHHHHHJFIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3043:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGANAAGAACCAAAACTATAA
++
+JJJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3188:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANAGTGGTGGATTAGTAGT
++
+JJJJJJJJJJJJBC#4ADDFHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3211:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGTAATGTAGTCTTTAAA
++
+JJIJJJJJJJJJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3145:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGGCTGTGGAGTAAAAAAAA
++
+HFHHDFFFDEEE at CCFFFDFHHHDHEHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3082:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTGTGTTGGCGTTTTATCT
++
+JIJJJJJJJJJHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3160:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTTGTTGGCCAAAAAAAAA
++
+FFFFFEEEEEEECCCFFEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3135:2214 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGACAGGAGAGGTGATCGGAGT
++
+############?=?D;2=2CDB22C:<A:??F
+ at HWI-ST960:105:D10GVACXX:2:1101:3213:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTTCTGTTGAAGGAGCTTTT
++
+HIJJJHIJJIHHBC at FFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3036:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATATACTTCACAACTCTG
++
+IJJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3140:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGCAAATAAGTCAAAACTTT
++
+HGHIGGHHHIGIB at CFFDDDFHFFHJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3106:2228 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTAGCTCGACCTAACACTT
++
+IIJJJJJHHHHHCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3085:2237 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTCATCAACTTTGTCTCTGCTT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3151:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATTCCATGTACTTACATTCC
++
+JJJJJJJJIIJICCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3041:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGTAATACCTTTTATATATAG
++
+IJJJJJIDHIJJCC at FFFFFHHHHHJJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:3218:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGCCCAAACTGCATGCACAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3400:2159 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNGAACTCTTCTTGGCTGC
++
+JJJJJIGEGIIJCC#4ADDFHHGHGIIIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3487:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTNGACATATATCAACTTTAC
++
+HIJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3325:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNATATTTCGTTGGACTGT
++
+IJJIIJJJJJJJCC#4ADFFHHHFHIIJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3342:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNGTTACTTTGATCCTGAA
++
+IJJJIJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3432:2166 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGCNCTGTGATTGCTTCGCCT
++
+JJJJJIJJJJJJCC#4BDDDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3370:2167 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNTCAAAGTGTTTCTTTGTT
++
+HIJJJJJJJJJJCC#4ADFFHFHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3440:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGATTGAAGGGAGCTC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3302:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAAGTCATGACTCATGAGCTA
++
+FHIJJIJIJJJJCCCFFFFFHHHHHJJJJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:3369:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTGTCATATTTGCGATGTAT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3257:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTAAACTCTCGTGTGGCT
++
+FHIIIGIJIJJHCCCFFFFFHHHHHJHJHIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3285:2210 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGAGATGCAAAACAGTAGTTT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3316:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAAATCTTAATCTCAAAT
++
+IGIIIIIJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3555:2158 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNGTAATCTGACTCTCTTT
++
+IJJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3609:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANGTTATGTTCTGGACCTAA
++
+HEHHIHCHGIIICC#4ADDFHHHGGIIEHGIII
+ at HWI-ST960:105:D10GVACXX:2:1101:3629:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNTTATGTAGAACTAAGAT
++
+JJIEFIJJIIIJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3522:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNAGTTCTTTTGTGCCTTC
++
+JJJJJJJJJJIJBB#4ABDDHHHHHHIJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3597:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCCCCCGTGAGTTACTTCAC
++
+HIIGG at ADHHHH@@?ADDDDCFHDHGIBGEGH@
+ at HWI-ST960:105:D10GVACXX:2:1101:3651:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATATGTAGGCTAAAAAAAAA
++
+HEEDFFFFEEEEC at CFFFEFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3568:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATTTATGTTTTGGACTTGT
++
+HGHIJJJJJJJJCCCFFFFFHHHHGJIJJJIH
+ at HWI-ST960:105:D10GVACXX:2:1101:3545:2181 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGTGTGTTGTGGTTTTTAT
++
+FCHIIIGIIHIG@@@ADBDDFHFFHFHGIIJG
+ at HWI-ST960:105:D10GVACXX:2:1101:3669:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTGTGTTGGCGTTTTATCT
++
+JJJJJJJJJJJHCCCFFFFFHHGHHGIJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3587:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAAGTGTAGAATGCATACAA
++
+IJJGJGIIIJJJCCCFFDFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3570:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTGTATGATTGAAGAAAT
++
+JJJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3530:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAACGAAAACTATTTAAAAT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3706:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGGCGAGTGTATCTCAACAA
++
+IJJGHIHGHHHF at CCFFFFFCFDDHHIGIHHGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3809:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANCTGTAGTTTTCCTTCCTT
++
+IJJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3872:2165 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGNGGTAGATATGAGGTTAA
++
+JIJIJJJIJJJJCC#4ADDFHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3775:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTACATTAAGGCAGTTCATTG
++
+IJJJJJJJJJJJCCCFFFFFGHHGHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3902:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCACAAATGAACTTAAACT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3885:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTACCTACTCGTCGTACATTTT
++
+==CCDCEE??AA@;@DDDDDAHDHFIIGGE at HH
+ at HWI-ST960:105:D10GVACXX:2:1101:3807:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATCTCGGACCAAAGAGAGC
++
+JJJJJJIJHHHHCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:3780:2206 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGCATGTTGTGCACCGGCTCC
++
+GHJIHHHHFFFFCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3853:2215 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCTCCGATGATGATCAAATCAT
++
+JJIGGIIJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3946:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAGTCTTTTGGTATTTTA
++
+JJJJJJJJJJJJCBCFFFFFHHHHHGHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3976:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTGTTCGGCTTTGGATTAAG
++
+IJJJJJJJJJJHCCCFFFFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3866:2227 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATACGATATGTATATGTAC
++
+JHJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3816:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAGGTCTTGTGTAGAAACT
++
+JJJJJJJJJJJJCBCFFEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3779:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTTGAGTTTCGAGTTATCTG
++
+JJJJJIJJJIIICCCFFFFFHGHHHJHIIJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3799:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTCTATCTACTACTTTTTC
++
+JIJJJJJJJJJJ at BCFFFFFHHHHHIJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3759:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAACTAGTATAGTCAGAAAAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:3912:2249 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCATGTGAACAAGAACATATCCT
++
+IJIJHIHJJJJJCCCDFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4038:2162 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGTNGATTGAGGTCGGCAACAT
++
+JJJIHHHFFFFFCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4099:2173 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTTGGCTCATGAAGTAAAATAA
++
+HIIJJJJJJJJJCCCFFFFFHHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4193:2190 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACTTTACAGCTTCTTCTTAT
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4045:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACTGTGTTGGCGTTTTATCT
++
+IJJJJJJJJJJHCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4171:2195 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGAAGTTGAAGAACCTATAA
++
+HIJJJJJEHIIJCCCFFFFFHHHHHJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4159:2232 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGTATCAAACGTAGAGGCAG
++
+IIJIJJJJJHHH@@@FFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4186:2233 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTAGTCAGCTGCAACACTTT
++
+IJJIJJJIJIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4072:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAACACCAAACAACTCTTTCT
++
+HJJJJJJJIJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4053:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGAGGTTTGAGATATAA
++
+JJJJIJJJJJJJCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4001:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCAAATGAGAACTTTGAAGGC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4493:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGNCGTTTGGACGTTGGTAC
++
+HHIIIIIIIIIH@@#4=DDDHFFHFE=DHACH
+ at HWI-ST960:105:D10GVACXX:2:1101:4487:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAGCATGTAGTTTGATGATC
++
+IIIGGICFHHII@@@DDDDDHDCABEBEBG>F
+ at HWI-ST960:105:D10GVACXX:2:1101:4487:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAATTGTTACGCAACAAACT
++
+HFI85DDBCEHH@@<BABADFDDDFGAFGHGC
+ at HWI-ST960:105:D10GVACXX:2:1101:4428:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAATATTTTTTCTATTCA
++
+8/=CC68.8=;=@:?BBD;AFBFFFBAGII<A
+ at HWI-ST960:105:D10GVACXX:2:1101:4264:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTTAATCTGAGTCTCTGCTT
++
+IIJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4422:2216 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACTTTACACGACAAAATAA
++
+HGIJIJJJJJJHCCCFFFFFHHHHHJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4332:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTCCGAGTACAACTTTGG
++
+JIIIJJJJIJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4424:2238 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTAATCTTGTGTCGGCAGGTGT
++
+HIJIHHHFFFFFCCCFFFFFHHHHHJJJJJBGH
+ at HWI-ST960:105:D10GVACXX:2:1101:4369:2249 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGATAATGATGATGAAAGATG
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4279:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATGTAGAACTCTTTGCTT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4589:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGNTTTGTTTGGTACTGAAA
++
+IIIIIIIIIIII@@#4=BDDHFHHFHIIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:4565:2165 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACNTGTGAAAATCTGATTAT
++
+IIIGHIIIIIII?@#4ADDFFHHHHIIIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:4583:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAGTGAAATACACTCTCT
++
+IIIIIIIIIIII??:B?ABBAB?DHGDHG>>@
+ at HWI-ST960:105:D10GVACXX:2:1101:4599:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTGTTATCGTGTCTGTAAGC
++
+JJJJJIJJJJJJ@@@DFFFFDHHBHIIJGJGB
+ at HWI-ST960:105:D10GVACXX:2:1101:4699:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTGCCTTCAAGTTAACTTTGT
++
+GIIHIHIJIJJJ@@BFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4615:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGTCTTCTTCTTCTGTATTA
++
+DBGDEHGIGG at C@@@FDDFDDFFHFHBAGDII
+ at HWI-ST960:105:D10GVACXX:2:1101:4505:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATCCTATGCTTTGGTCATAT
++
+IIIGIGGGGIII@@?DDADDH?FHFE<CEHFH
+ at HWI-ST960:105:D10GVACXX:2:1101:4515:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTACTTAGACTCATGCTTGT
++
+HIJJIJJJJJJJCCCFFFFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4695:2199 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAATGACTGTAACTTACTCTTC
++
+HIJIHIJIJIJJ at CCFDEFFDHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4586:2200 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATAGGAATCTGTAACTTTT
++
+IJJJJJJJJIIJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4624:2201 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATTTGCGATGTATCATGTAT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4717:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTGGTTTATTTACATGTTT
++
+JJJIJIJJIIJJ at BCFFFDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4738:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAGCTTCTCTGTTATGTCT
++
+HIJJIJJIJJJJCCCFFFFFHHHHHJIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4745:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTGATATCTAAGCTTATGT
++
+JJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4619:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTCAGATTTCTTACATTCAA
++
+IIJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4707:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCAGTGTTTGTCTGAACTCTG
++
+IGIIJJJJJJJJBCCDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4784:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCNGTACTGGTACTGTAATA
++
+JIJIJJJJIJJJ at C#4ADDFHHFHHJJHEGHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4903:2162 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNGACAAGTTGGTTTCGAT
++
+IIJJHIJJJJJJCC#4ADDFHHHHHGIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4957:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNTGTCCTCCAGACAACCC
++
+HIJJJJJJJJHHC@#4ADDFHHHHGJGGIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4807:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTNGTTTGTGGTTAGTGTCA
++
+IIJJJJJJJJJJBC#4ADDFHHHHHJJHIIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4863:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNGTTGCGTAAGAATCAGGA
++
+HJJHHIJIIHHHBC#4=BDDHHHHGIJGIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4754:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATCGTCGTCAAGCCTGCCAC
++
+HGJIGIJHHHHHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4768:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAAACTTCTCTGTTTAGTTTGT
++
+BDFFGDHIDHDF@@?DDDDDHHDDDFCH<?EEH
+ at HWI-ST960:105:D10GVACXX:2:1101:4842:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAATCATTATAGAGATGGT
++
+HIJIJJJJJJJJCCCFFFFFHHHHGJJJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:4964:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCAAGTCATGACTCATGAGAT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4787:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAACAAACTTGCATGTCGGCAC
++
+IJJJJJJJHHHHCCCFFFFFHHHHHJIJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4867:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCTTCTTTCCAATCTTATCAC
++
+JJJGIIJJIJJJ@@@FFFFFHHHDFGIGGIHII
+ at HWI-ST960:105:D10GVACXX:2:1101:4934:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTAGTAACTGAAAACG
++
+IIJIJJJJJJJJCBCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4988:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTCTTTCTCGAGAAATCGG
++
+JJJJJJJJJJHHCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4973:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGCTGTAATTACAGATTGAA
++
+JJJJJJJJJJJJ@@CDFFFFHHHHGIJIJIGG
+ at HWI-ST960:105:D10GVACXX:2:1101:4783:2210 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCGATGAATACATCATGGTAGTG
++
+IJJIJIGHIIJJCCCFFFFFHHHHHJJJGHJII
+ at HWI-ST960:105:D10GVACXX:2:1101:4861:2212 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATGTTTAGTTTAGAAGAA
++
+FHIIJIJJIIIJ@@@FFFFFHHBHHJIJIIGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4929:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACTGTGTCTCATCACTCAA
++
+IIJHJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4966:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATATTCAAACTCTTGGACTGA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:4877:2249 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCCTTCCTACTTGAAGAAGGTTG
++
+IJJJIIJJHHHHCCCFFFFFHHHHHJJJJJHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5072:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGCNTGTCCCTTACTCTGTAT
++
+JIJJJJJJJJJJCC#4ADFFHHHHHJJIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5006:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTNTCCTCTGAATATTTCTA
++
+HGIIJJJJJJJICC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5029:2168 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTTTTGGTTCTGTAGACACAC
++
+IJJJJJJGIJJICCCFFFDFHHGHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5174:2170 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATATAATATTCCCTAAGAA
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5153:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATACCCCGAAAATTAGATC
++
+JJJJJJJJJHHHCCCFFEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5078:2188 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCTTGGTCTGGTGGTAACAAT
++
+HIJJJJJJJJJJCCCFFFDFHHHDHIGHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5182:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTTGTCAACTTCAATTTCAG
++
+HIJIJJJJJIJJCCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5054:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTACTGTATCTCATTAGCTGA
++
+HIJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5208:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGTTTCTCTTGGAACGAA
++
+HIJIJJJJIJJJCCCFFFFFGHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5105:2206 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATGAACTGTATTAAACTTTT
++
+JJJIIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5029:2212 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAACATTTCGAACAATGAACAA
++
+HIJJJIJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5084:2222 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTACCTCTCTCTGACTTCAC
++
+IJJIIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5223:2223 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCCGGAGTTTTTTCAGCAGTTC
++
+JJJJJJJHHHHHBCCFFDDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5173:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATGTGTAATGATTCCTTC
++
+JIJJJJJJJJJJBB at FFEFEHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5208:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTTACTTTGATCAGAAATT
++
+JJIFHIIGHIJJ at BCFFFFFHHGHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5101:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAACTCTACCTTTATTACAGT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5189:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTACAAAACTTTCTAATTTG
++
+IHJIJJJJIJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5018:2248 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATGTAGAATATGAGTTTA
++
+IJJJJJJJJJJJBBCFFDFFHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5160:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTGCTTGATTTTGAAGTTAG
++
+IJJJJJJJJJJJCCCFFFFFHHHHHIJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5491:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNCTAAGATTCGACCCTCCC
++
+HIJJJJJHHHHHCC#4ADDFGHHHGIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5363:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNTGATTGTAGTCAGAACC
++
+IIJJJJJJJJJJCB#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5471:2159 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGNGGGTTTGGCTTGAAACTC
++
+HIIIIIIIIGIH@@#4=DADDFHFHIIGGII at E
+ at HWI-ST960:105:D10GVACXX:2:1101:5293:2163 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNATAGACCAAAAGCAATTC
++
+IJIJJJJJJJIJCC#4ADDFHGHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5262:2165 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCNAACTTTGAGGCTTAAAAA
++
+HJH<DDE@@AC=CC#4ADDFHGHHHJJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5313:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNTCATATTTGCGATGTAT
++
+JJJJJJJJJJJHCC#4ADDFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5498:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGCGAGAGTTCTTGAACTGA
++
+IJJJJJJIJJJJBC at FFFFFHFHFHGIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5435:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATAAGGACTGTGAAGTGTG
++
+JIIJIJJJJJJJCCCFFFFFHHHHHJJJGHJI
+ at HWI-ST960:105:D10GVACXX:2:1101:5472:2190 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCACTGTAATCTCACGGTGTGT
++
+IIJJJJJIJJHHCCCFFFFFHHHHHJJJHHGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5358:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTAATGTAGTCTTTAAA
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJIIHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5420:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCGTTTGATTTGCAAGCTG
++
+HEIJIIJJJJJJCC at FFFFFHHHHHJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5318:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTTGTAGCAAGGCACTGAT
++
+IIJJJJJJJJJJCCCFFFFFHHHGHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5357:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTCATTTCTGCTCTTATCAC
++
+BBF at FCGHDFGH@@CDDFFFFHDDHIIIG at EIG
+ at HWI-ST960:105:D10GVACXX:2:1101:5300:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATGTAGAACACACATGATTT
++
+FBF=CFEFGEEE?@@?DDD;:DBFFFFIF+AIF
+ at HWI-ST960:105:D10GVACXX:2:1101:5485:2228 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAAATATCGTATCCGTTCAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5295:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAAAGACTTGGACCTTCTTTC
++
+B=FHFBDF===C@?@DBDDBFBFHHGGIIGGIB
+ at HWI-ST960:105:D10GVACXX:2:1101:5281:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGAGCGTACCGACATGCGGT
++
+EFFDFFDEEEEECCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5593:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANCTTAGAGTCTGTTTTTT
++
+HGIFHHHHHEEE@@#4=BDDHH?FHHFHIIEI
+ at HWI-ST960:105:D10GVACXX:2:1101:5636:2160 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTNCGATGATGATCAAATCAT
++
+IIJGJJJJJIGICC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5558:2161 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNCTTGGGTTCAACTGCCTT
++
+=BCFFCFF at EEE?:#4=BDDFCFFFFCED at EBH
+ at HWI-ST960:105:D10GVACXX:2:1101:5611:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNAGAACTTGATCATGCAT
++
+IIJJJJJJJJJJC@#4ADDFHHGHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5679:2172 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAACAATATTCTCATGCACCT
++
+HJJJJJJJJJJJCCCFFFFFHHGHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5663:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTGTAATCTGACTCTCTT
++
+IGIG?HIJHIJJC at CFFFFFHGHHHJJJIJII
+ at HWI-ST960:105:D10GVACXX:2:1101:5539:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTGAAAGAAAGAGCCATTGGT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5728:2197 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCTGTATAAATAGTTTTAA
++
+HHJJJJJJJJJJCCCFFFFFHHHHHJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5500:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTATCAATTGAACTAGATTCA
++
+IJJIJJJJJJJJCCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5592:2204 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCAATAAAGCTGTTGAATGAGAT
++
+HJJJJJJFHIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5553:2233 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGATCTGTAAACTAAAAAAAC
++
+IJJIJJHHFFFFCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5604:2241 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTTGATTACCATAGCATTT
++
+JJJJJJJJJJJJCCCFFFFFHGHFDIHIJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5743:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGGTTTTAAGTTCTTAGAAC
++
+IJJHJIJJIJJJCCCFDEFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5682:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTTGAGTATGTAGAATCTG
++
+IIJJJJJJJJJJCCCFFFFDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5999:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCNCTCTCTCTTTAGTTGTT
++
+JJJEIJJJJJJJCC#4ADDFHHHHHJJIJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5979:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTCTCTAGAAAATATCAGA
++
+HIJIIJJJJIJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5958:2186 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGCGATGATGATAAAATAGC
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:5985:2215 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATAGTTTTGTTGTTTCTT
++
+IGIIIIJJJJJJCBCFFFFFHHHHHJHJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5952:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAGCAGTACAATTGCAGAAGT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5970:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTTATGTAGTCTCATTTCCT
++
+HBGDHGHIIGGI at CCFFFFFHDFHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5909:2233 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCACCAGTTTTACAGAGTGTTT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJEHHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5792:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATATACTTCACAACTCTG
++
+JJJJJJJJJJJJCBBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:5990:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACGGGAAGGTGATATTTGCT
++
+JJJJJJJJJJJJ at CCFFFFFHCFHGJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6177:2163 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTANCATCGCTTCGTTTTTAT
++
+HHJJJJIJJJHHC@#4ADFFHHHHHHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6014:2179 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTACTTCTAAGTTTAGTAAC
++
+JJJJJJJJJJJJCBBFFFFFHHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6138:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTTATATGAACCAATAATAG
++
+FGHIGGHIIJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6181:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCACAAAATATATAGGAAGT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6001:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTGTGAATCTGATTATACAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6161:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAGTCATAATAATAGTAGC
++
+GHIJJJIJJJJJ at BCFFDEFHHHHHJJJJHHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6053:2206 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGTTGGCATGAGAACCAA
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6128:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATTGTTGTACTCTTTAATAT
++
+GIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6082:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTTTGTGTGAAAAAAAAAA
++
+B;CECAEDDDDD at CCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6229:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTTGGTGAAGTTTTTAAGT
++
+JJJJJJJJJJJJCCCFFFDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6024:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAAACCTATAATATTTCTT
++
+IJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6181:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCGGCTAATACCTAATGTCA
++
+IGIIIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6060:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGAATCATGTTGCTTTACT
++
+HHIJJIJJJJJJ at B@DFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6084:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATGTGTTCTCTCTGTTCAA
++
+IGIJIJJJJJII at CCFDFFFHHHHHJJHGIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6273:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNACTGTCTTTGGACCCTTT
++
+GGIBHFCHGGFF=@#4=BDDFHGHHJIGIJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6431:2161 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTANTGGTGATTTGTCTGTAT
++
+IJJJIIJJJIIJCC#4ADDDHHHHHGHJIHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6304:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNTGATGTTATAGTAAGCAT
++
+JJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6492:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTCACATTATGAATATCAA
++
+JJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6252:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATATACTTCACAACTCTG
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6273:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATGTTGTCTCTCCCTCTTAT
++
+IJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6457:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGTGAAACTCTATCAATTCA
++
+JIIJIJJJJJJJBC at DFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6377:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGAATATGTTGCTGTAGTCAC
++
+IHJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6427:2203 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCAAACCAGAGACAAATGACAC
++
+JIJJJJJJJJHHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6279:2218 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCTTGGACTGTGAAGTTTGGCT
++
+JIJHGGGICGHHCCCFFFFFHHGHHGGIJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:6366:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGATGTCGGCGTTGAATAAA
++
+IJJHHHHHHFFFCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6393:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATTGCAGTAGAACATAAGT
++
+IHIJJJJJJJIICCCFFFFFHFFHHJJIIJIF
+ at HWI-ST960:105:D10GVACXX:2:1101:6268:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAACTCTTGTGTACCATAAAAA
++
+IIHIIJJJJJJJCCCFFFFFHGHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6467:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATCACCATGTTCCAATTTC
++
+IGIIJJJJJJJJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6481:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATACTAGTGTTTAAGAAGTT
++
+IJJJIJJJJIJJ at CCFFFEFHHHHHJJJGIJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:6397:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTAACTTTGGCGAATGGATAC
++
+@@FFGGII;AHC@??BDDADHBFDF?CFEGIGI
+ at HWI-ST960:105:D10GVACXX:2:1101:6429:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTATATATGGAGAAAATGGA
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6523:2161 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNAGTACTATGTTCTCATTT
++
+FCFIGIIIIGEF@@#4=2ADFBDAFFFIIBHII
+ at HWI-ST960:105:D10GVACXX:2:1101:6687:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTNGTAGACTCTGTTTTGTC
++
+IIJJJJJJJJJJCC#4ADFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6525:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTGTAAGCTGAGGAACTCT
++
+IGIJJIJJIJGICCCFFFFFHGHHHJGIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6517:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGGCACGGCTATGAAATCT
++
+IHGBEIGHCHHH at CCFFDFDDFHHGIEIIIGGH
+ at HWI-ST960:105:D10GVACXX:2:1101:6700:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACATCTCACTGCTCACTACTC
++
+HJJGJJJJGIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6538:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGCTAGAGAGAGGAGGAGAC
++
+JJJJJJJJJJHHCCCFFFFFHHHHHJJJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6575:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTTTAACACCTCTACTTTT
++
+HIIHIJIJJJJJBB?DFFFFFGHHHJJJHBHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6501:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTTTATGGCTCTAGTACAAGC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJGIIIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6631:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTATCTCTAAAATTGCAAAT
++
+JJJJJJJJJJJJCC at FFFFFGHHHHJJIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:6672:2205 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCATGGTTGCTTTAATATTTTT
++
+JJJJJJJHIJHHBCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6579:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCGACTTTGATCCAAAAAAAA
++
+HAHEHHGFFFFFC at BFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6552:2217 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCATCTTTAGCTTTATTTACTC
++
+IJJJGIJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6685:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATTATTATCAATAGCTCTTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6503:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTAGGGGCTGATTTGTCTT
++
+JJJJJJJJJJHHCCCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6613:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCTACCATTATGCACTATTT
++
+IJJJJJJJJJIJCCCFFFFFHHHGHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6670:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCGGCGTGAAAGGGCGACTAAA
++
+HHHHFFFFEEEECCCFFFFFHHHFGEIGIGIJH
+ at HWI-ST960:105:D10GVACXX:2:1101:6721:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAAACTTTCTTAGCTTGTCC
++
+IJJGIIJJHIJICBBFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6642:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGGGTGATGAACGAAATAAAAA
++
+IIJJJJJJJJJJBCCBDFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6589:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTAAAGACAGAGAGATAGA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6684:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGATCGAAACCAAACACCGAT
++
+IGJHHHHFFFDECCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6942:2160 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANGGTCGATTTAGTTAAAA
++
+HGIIJIJJJJFI@@#4A=BDHHHHHJGGIIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6987:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTANACCAGCTGAAGAAAAGGC
++
+HIJIIJJJIAEHCC#4ADDFHHHHHJJJJJJIF
+ at HWI-ST960:105:D10GVACXX:2:1101:6968:2161 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCATNTTGATCGGATGGGCAGAA
++
+GIIHGGIJHHHHBC#4ADDFHHHHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6922:2166 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTNTGGAACTGTGGATTAAAA
++
+IJIIJIJJJJJJCC#4ADDFHHGHHIIJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:6902:2167 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCNTCTTATTCTTTCTCTTT
++
+IIJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6830:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTGTCATTCTCTAAATAAC
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6954:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATAACTCTCTCGCCTTTGT
++
+IJJIJJJJJJJJCBCFFFFFHHHHHJJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:6754:2179 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAAGTCGTATCTAGGTGTGT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJGHIHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6877:2188 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACAAAGTCGTTGTAGTATAC
++
+JJJIJJJJIJJJCCCFFFFDHHHHHJJJIHJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6970:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATCACACTGTCAAATCCGAA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6918:2197 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTCGGCTCTGTTCATATAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6851:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTTCTGGCTGTAGAATCTT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6836:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCACGCACACCGCGTGTAGAG
++
+IHHHHHHFFFFFCCCFFFFFHHHHHHJHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6948:2228 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCCGATAGAGAACCTTGCTGACC
++
+HIJJJJJJJIJJCCCFFFFFGHHHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6923:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATTTTATGTGGTGTTACTT
++
+IJJJJJJJJJJJ at BCFFFFFHHHHHFHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6971:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCAGTGATGAAATTATGTC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6883:2236 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGAGTGAGATATAAAATGGG
++
+IJJJJJJJJJJJCCCFDFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:6822:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGAATTCAGACTGTGAAACTGC
++
+IDHIIEG:FHIH??;AD?DAFBAFCEHHIEGGC
+ at HWI-ST960:105:D10GVACXX:2:1101:7194:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTNCTTTATATGAACCAATAA
++
+C8B88FF:C3=@@@#4=AD;FBFFDBFBBF?FA
+ at HWI-ST960:105:D10GVACXX:2:1101:7080:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCNGGATTCTCACTCTCAGC
++
+HHJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7018:2176 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGGAGTTTTTTCAGCAGTTCT
++
+JIJJIIJDHIJJBCBFDEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7182:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTGTATTTGTGCGTGTAGC
++
+JIJJJJJJJJJJBCCFFFFFHHFHGJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7145:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATAATAAGACTCTTAATCAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7091:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGTAATGTAGTCTTAAAA
++
+JJJJJJJJJJJJBC at FDEFFHHGHFHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7123:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTCCTTGACTGGAAAAATGT
++
+JGIJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7068:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATGTACCGATGCATAGT
++
+HHJJJIJJJJJJCBCFFFFFHHHGHJJHIIEH
+ at HWI-ST960:105:D10GVACXX:2:1101:7245:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTTACCATGGAACGAACAT
++
+HJJJJJJJJJJHCCBFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7109:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTGTAATTCAGTTAGCTCAA
++
+IIIJJJJJJJJJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7209:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGTCAATGCATAGACAAAA
++
+JJJJJJJJIJJJCCCFFFFFHHHHHJJJJJJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:7060:2201 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGTGTGTTGGTGGATATAAC
++
+IGJJJJJJJJJJBBCDDEFFHHHFHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7155:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTGTTGGCCTTTAAAAAAA
++
+HDGBGHHFFFDDC at CFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7198:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATATATTTCGTTTCATTT
++
+HGIJGHIJJJJJCBCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7115:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAGGCTGTGGAGGTTATC
++
+HIIIIIIIIIIICCCFFBDFHHHGDGGHHHAH
+ at HWI-ST960:105:D10GVACXX:2:1101:7149:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGTTAGACTCTTCGATTT
++
+IJJJIJJJJJJJCBCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7127:2244 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTAGATACTGATATTA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7018:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTTATATGAACCAATAATAG
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7448:2162 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAGNGTGGATGCTGCGGAAGAT
++
+GGIJIJHHHHFFBB#4=DDFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7352:2162 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNTGTTGTGGGTGACTTTGA
++
+IJJJJJJJJJHHCC#4ADFFHHFHDGHJJJIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:7420:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACNGTGTTGGCGTTTTATCT
++
+IJJJJJJJJHHH at C#4=DDFHHGHHIJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7296:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCNATCTGTCGTACTGTTGT
++
+IJJJJJJJJJJHCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7382:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAGTAGACTTGCAAAGATCGT
++
+HIJJJJJJJJJJB@@DDFFDDHHGHJIIJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7449:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATACCCCGAAAATTAGATC
++
+IGIJJJJJJHHHBCBFFFFFHHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7359:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGGCTGATTGTAGAATGGTT
++
+HGHJJJJEGIII@@@FF>DFHFFFFGIIJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:7292:2202 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTCAATCCATGGTTTTCTCAAAGTTTTC
++
+HJJJJJJJJJJJCCCFFDFFHHHHHJJJHIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7393:2205 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTCTCTGTACTGTAAC
++
+JIJIJJJJJJJJC at BFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7359:2210 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCAGAGATCGGAAGAGATGGCTT
++
+JFGGHHJJGEHH at C@FFFFFHGHAFGIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7415:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTAATTATTCGTATGAACT
++
+IIJIJJJJJJJJ@@CFFFFFHHFHHJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7403:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCGTCTTACCATTTCTTTCAT
++
+III@=F4./@FI@@@A?DD>AC>BF at GFGBHI
+ at HWI-ST960:105:D10GVACXX:2:1101:7373:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGTCTGTCTAGTCTATTG
++
+IHIGIJIJJJIJ at CCFFFFFHHHHGHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7324:2231 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATCAAATGTATTATATATAT
++
+IJJJJJJJJJJJC at CFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7309:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTGAGTTTTTACATGTTTGT
++
+IIJJJJJJJJJJ at BBFFDFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7475:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTGACTGTATTGAGCAACC
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7687:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTNTAGTCTAAGGCTTTTCAA
++
+HIJJJJJJJJJJCC#4BDDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7649:2170 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTGAGTAGACAATTTAATCA
++
+F?B at FHGIJGEH@@@FADEFHHHFHJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7708:2170 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGTTTAATAAAACAGAACAA
++
+IJJJJJJJJJJJCCBDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7709:2191 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCTCTCTCTTACCTTTCTCT
++
+JJJJIJJIJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7690:2197 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTCGATTAGTACCGTTAGTG
++
+IIIEIHIJJIHHCCCFFFFFHGHHHJIHIIJIG
+ at HWI-ST960:105:D10GVACXX:2:1101:7607:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCCGGAATGGTGCCTTTGTTAC
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7698:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTCTGGCTTTGCTCAGATTT
++
+IJJJJJJJJJJJ at BCFFFFFHHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7518:2217 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAATTCTTTTACCGGGTTGAG
++
+HHIJHJJJJHHHCCCFFFFFHHHHHJJGHJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7534:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAATGAATGTTTCGGACTTC
++
+FFGIJIEHIJGH at CCFFFFFHHHHHJJIGIIJG
+ at HWI-ST960:105:D10GVACXX:2:1101:7679:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCGGTGAGTGGAACTTCTT
++
+IJJJJJJJJJJJBCCFFDDDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7747:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCACGAGTCGAGGCTCTCAATA
++
+HJJJJJHHHHHHBCCFFFDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7610:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCAGTGGTAGAGCGCGTGGC
++
+HHHHHFFFFFFECCCFDFFEHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7532:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATGTTCACTGTTCTCTGC
++
+DBFFCCFHGGEG?@CFDDDDHHHHHGGJJGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7676:2238 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCCAGCCGTCGGATACTGACTT
++
+IIIIIHHACHHF<@@FFFFDHHHHHDDHIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:7641:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCTGTAGCCTCTCTTTTAGT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:7824:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNAGTCTCTTTTTTGAATT
++
+GGHDHHIEGHGH@@#4=ADBFHHHGIIGIGGI
+ at HWI-ST960:105:D10GVACXX:2:1101:7876:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAANACATGGGAAAATATGTG
++
+==='566A@===@@#442AAAD?CB?C at G>IB
+ at HWI-ST960:105:D10GVACXX:2:1101:7774:2165 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTCNAACGAGGAAAGGCTTAC
++
+JJJJJJJHHHHFCC#4ADFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7839:2165 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTNTAAAACTGTGCCATTAT
++
+IJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7920:2167 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAANTTCTTTATACTTTGTAAA
++
+HIJJJJJJJJJJCC#4ADFFHHHHHJJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7966:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGCAACTGCAAATTCTGCA
++
+JJIJJJJJJJJJCCCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7948:2186 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTGCTGTGGATGATCTGGT
++
+HIJJIJJJJJJJ at CCFFFFFHHGHHJJJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:7864:2190 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGGAAGAACTCTGGAAGTGAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7912:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACAAGATGTTTAATCATCC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7970:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACAATTGTTGTCTTGTAGTA
++
+IIJGHJJJIIGJ at C@FDFFFHHFFAHIHIJHH
+ at HWI-ST960:105:D10GVACXX:2:1101:7819:2202 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAATTGTTTCTTAGCATCT
++
+IJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7762:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTACTTTATAAGGACTGTGAA
++
+IJJIJIJJJJJJCCCFFFFFGHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7847:2207 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGCAACCCTGTCTTGCTTTA
++
+IJJIIJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7775:2219 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTATTGTGTTACTGAATCTT
++
+JJJJJJJIJJJJCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7900:2219 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTACGCCCGAACGCAAACC
++
+HFFFFDDDEDDDCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7800:2227 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTCTTATGATGTCAAAACTTTC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7973:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTATGTGTTCTGCAGATCGA
++
+IIJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7844:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTCGTTGGGTTTTCTTCAT
++
+IIJJJJJJJJJJ at BBFFFFFHHDHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7863:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAAATTTTCGAAGGAGACAA
++
+HIJJJIJJIJIH?BBFFFFFHHHHHJIJJIGII
+ at HWI-ST960:105:D10GVACXX:2:1101:7912:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGTGTGTAACCTCATATGGAC
++
+IIJJGIJJJJJJCCCDFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:7940:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCGTGTCAAGTGTAGAATCAA
++
+IJJJJJJJJJJJBBBDDFFFHFHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8088:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCANTGGAAGGCTGTGGAGGA
++
+IJJJJJJJJJHHCC#4ADFFHHHHHHIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8140:2163 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCCGNTGGGTTGGGGATCCGGT
++
+HEHE at DBDBCCC@@#4ADB=?DDDHIAFBE@?
+ at HWI-ST960:105:D10GVACXX:2:1101:8156:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNTGTAAGTATGAACAAAA
++
+IIIIJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8057:2166 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGNAACATTGAACAAGCAGTT
++
+IJJJJJJJJJJJCC#4ADDFHHHHHJJJJIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8023:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGTATCTTGTTGTTTATCTA
++
+HIJJJJJJJJJJCCCDFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8157:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCAGTGGTAGAGCGCGTGGC
++
+EHHFHHFFFFFF at BBFDFFDFHGHHJIJIIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8117:2186 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCACTGAATCGACTTTGGGCAAA
++
+HJJIIHFHIJJJCCCFFFFFHHHHGGIJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8197:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGGTGCTTAAAAAAAAAAA
++
+C;@>BBDDACCA at CCFDEFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8236:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTCGGCTTAAACTCTAT
++
+FGIIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8088:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGGAAATGTGCTATGGAC
++
+JJJJJJJJJJJJCCCFFFFFHHFHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8085:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCGCAGTCGCTAAGCGTCAC
++
+JJJJJHHHHHHFCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8003:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATATTTGTGGATGATGAAGA
++
+IIJJJJJJJJJJCCCFFFFDHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8138:2242 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTATATGATTCTACTTAGTCA
++
+IJJJJJJJEIJICCCFFFFFHHHHHJJJJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8069:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGGTACTATGAACATTGTGAC
++
+HGIIGGIGHIII at CCDDFFFHHGHHJJJIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8445:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNAGATTAGACTCTGTTTGC
++
+IJJJJJJJJJJJCC#4ADFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8271:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTNTGTATAATTGGAACAAG
++
+HIJHGIJIHIGIBC#4=ADFHHHHHJIJIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8390:2167 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNCGTGTAGAAGGGAAATGA
++
+IJJJJJJJIJHHCB#4ADDFHHHHHJJJJJIII
+ at HWI-ST960:105:D10GVACXX:2:1101:8355:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATGTGTAACCCTGTCCTT
++
+IJJJJJJJJJJJCCCFFFFEHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8375:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATATTGCTATAGAGTCACGCATCT
++
+IJJJJJJJIJJH at CCFFFFFHGGFHIIIGIJII
+ at HWI-ST960:105:D10GVACXX:2:1101:8257:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACCTGGAGACTCATGTGTTGA
++
+IJJJJJJJIJJIBCCFFFFFHHHHHJJIJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8438:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTGGTTTGGATTTTGGTTA
++
+IJJJJJJJJJJJCCCFFDFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8299:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCTCTGGCTGTTGAATAGA
++
+IJJJJIIJJJJJCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8333:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGCTTGCAAGTTCTCTCTGAA
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8309:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTGTGTTGGCGTTTTATCTG
++
+IJJJJJIHFHHH at CCFDFFFHHGHHJIIJIJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8363:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCAAGCATGATGAATTGATGAG
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8494:2200 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGCATTGATTGTGGTTAC
++
+HIJJJJJJJJJJCCCFFFFFHHGHHJIJIGGJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8291:2212 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTCTACTCTACTAAACCTCTGT
++
+IJJJJJJHIJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8482:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATCTTCCGTCTGTTTCTGAT
++
+HGIHIIJIHHGICCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8322:2218 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTTGACCGATGCTCGGACAA
++
+HGHHHHHFFFFECCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8388:2225 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGTGTGTATTTAGTAATTCAT
++
+JJJJJJJGIJIJ at B@DDEFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8442:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTTTCTATGTTGTTTGGTAG
++
+HIJJJJJJJJJJCCCFFFFFHHHHHIJJJJFII
+ at HWI-ST960:105:D10GVACXX:2:1101:8339:2233 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCATCTCTAGAACTCTTTATAAT
++
+HIJJIJJJHIJJCC at FFFFFHHHHHJJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:8376:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGTGTCAGATTCTAAAAAA
++
+IIIIIHHIIIII@@CDFFDFHFDHHBHGIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:8457:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTCTGTGGATTATGCTTTA
++
+IGIJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8675:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNTAGTAGAATTGGTTGCAT
++
+IGIIIIIIIIII@@#4ADDDHHHHHIIGIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:8657:2165 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGANCGTTTCTCTAGTTTTGT
++
+IIJJGJJJJJJJCC#4ABDDHHHHHJHIJJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:8627:2171 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGGTAAATTTGTCTGAATTA
++
+JIJJJJJJJJJJBCCBDFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8743:2178 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCATCTTTTCTTATGTAAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJIHHJG
+ at HWI-ST960:105:D10GVACXX:2:1101:8722:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTAGAGAAAGTGATTA
++
+IIJJJJIIJJIJCBBFFFFFHHHHGJ<EHIEG
+ at HWI-ST960:105:D10GVACXX:2:1101:8678:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGATGTATATTTACGAGATGT
++
+HJJJJJJJJJJJBC at FFDFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8565:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTCCTTCGGATCACTCAATT
++
+HJJIIJJJIHHHCC at FFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8583:2192 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAACGCTTTTATGTGCTTCT
++
+HIIIIJJJJJJJCB at FFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8633:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATACATATTGGGTTGTGATT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHHIJHHIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8687:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTTCTGTAGACTATGTGTTG
++
+JJJJJJJJJJIJ at B@FFFFFHHGHFIIGHHJEG
+ at HWI-ST960:105:D10GVACXX:2:1101:8605:2201 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTTTCTTGTCTAGTCGGTTTAT
++
+IIJIJJJEHIJICCCFFFFFHHHHHIJJHIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8532:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATGAATGTGTAGAAAAAAA
++
+HIJIJJHHHHHFBCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8688:2216 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTGGGGAAGGATCAGATGCA
++
+HGIIJJJJJJIJ at BBFFFFFHHHHHIIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8560:2228 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATTGGTGCCTGTAGGTCAG
++
+HIJJJJJJHHHH at CCFFFFFGHHGHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8658:2230 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTGCTATAGAATCTGGACAAA
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8538:2232 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTTATCTTTTACTTTCCTC
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8669:2248 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTACTGTTTTTTCCGCCTTC
++
+HIJIJJHHHHFFCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8931:2159 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNGCAGTCTCTGTAGAATAA
++
+JIJJJJJJJJJJCC#4ADDFHHHHHIIIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8978:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNAGTGGATATATTCATTAC
++
+IIJJJJJJJJIJCC#4ABDFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8804:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGNAGAAGTGTTAGATATAGT
++
+HJJJJJJJJJJJBC#4ADDFFHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8917:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATGTTGTTGTTGCATGCTGTG
++
+JJJIJJJJJJJJBCCDFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8755:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGATGTCGTTGGGTCTTTGT
++
+B==/;6.;==A?@@@DDAD?FHF??FEEED at AH
+ at HWI-ST960:105:D10GVACXX:2:1101:8885:2196 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTCCGATGATGATCAAATCAT
++
+IIH:F;@FDHII@@@DABDDHDBFHAEHFHAE
+ at HWI-ST960:105:D10GVACXX:2:1101:8967:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTCTTTATTCCTGGGTTGT
++
+IJJJIJJJJIJJCCCFFFFFHHHHHJJJJGHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8797:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTAACTCTTGCCTCTTCTT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8831:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTGGGTTTGTGGTGGGGGT
++
+EEDDDDDDDDDDBCCFFFFDHHHHHJEGIJJJF
+ at HWI-ST960:105:D10GVACXX:2:1101:8957:2220 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTCTTTAGCATCGACTGTT
++
+IJJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8751:2221 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTGTTTGTGTTTAAGTGCT
++
+HIJJJJJJJJJJBCBDDFFFHHHHHJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8914:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCGTTTTGGCTTTCGTTCTGT
++
+JJJJJJJJJJHHCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8937:2229 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTGGAATGATGATAACGATTTT
++
+JJJJJJJHHGIJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8832:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTGTCAGTCTAAGAAAATG
++
+IJJJJJIJJJJJBCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8894:2244 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGAATGTTTAAATTGGATCAA
++
+IGIJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:8849:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTACTGTAGTATATATGAT
++
+JGIJIJJJJGHJBCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9183:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTANAACCTGTTGAATTTATA
++
+IIJJJJJJJJIJCC#4ADFFHDHHGIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9200:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACNTAGCGAAATGCGATACTT
++
+HIIIIGHEAEA@@@#4=DDDAFFHHDHIIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:9117:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCANTTTAGTTTGGTACTAAT
++
+HIJJJJJJJJJJBC#4ADDFFHHHHGIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9238:2160 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTANATTATACAATGTCTCTGT
++
+IJJJIIJJJGIJCC#4ADFFHHHHHJHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9130:2168 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGGAATTGTTGAGTTTGGTA
++
+IIIB=B;@=@FI;?@BADDDFF?ADEFFEF<A
+ at HWI-ST960:105:D10GVACXX:2:1101:9203:2174 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTTGACTGTGATTTAAACGAG
++
+==FB at FDDF@@E??@DDEDDDHAHHGGIIEEF
+ at HWI-ST960:105:D10GVACXX:2:1101:9183:2182 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTACTCTATCTTAAACATGT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:9125:2192 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATCGGATTGTCAAATGTCT
++
+FHHIIGHIJJGICCCFFFFFHHHHHJJJICJH
+ at HWI-ST960:105:D10GVACXX:2:1101:9001:2202 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTCTTGTTGTCTAACTCTC
++
+IGI67B at A7CEH@@@DDBDDD?CDDGHBFAFE
+ at HWI-ST960:105:D10GVACXX:2:1101:9175:2204 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCTGAGAATAAGAACATACATAA
++
+JBFHHHIIJIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9224:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCGTAAAAACTTTGGGATGC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9118:2208 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATAGTTCAGTCGACATGAAT
++
+IJJJJJJJJJJJCCCFFDFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9087:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATATGGATGGATAATTTTCT
++
+IJJIIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9013:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGGAGCCTCTGTAATTTTGT
++
+JJJIJJIIGIJJ at CCFFFFFGHHFHJIGIJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:9153:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTCTTCGAATGACGAGTTCC
++
+JJJJJJJJJJJJC at CFFFFFHHHHHJJJGIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9188:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCCTTTGTCGCTAAGATTCGA
++
+HIIIIJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9022:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAAATAAACACATGTACTT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9098:2234 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGAGGAGAGCAGTCTATTCTG
++
+FFHGEHGIJJHI7@@FFFFFGHHHHIIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9115:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGTTTAGTTGGCGGTTTCAC
++
+IJJEHHFFFFFE at BCDFFFFHHHHHJJGHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9136:2239 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTGCTTCCTTTAACAAAA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9346:2162 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNCATGTCACATGAACGA
++
+HHIJJIJJJJJJBC#4ADFDHFHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9443:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCANATTAATCGAACTAAAGAA
++
+IJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9477:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTTATGGCACAACATGTAA
++
+IIJJJJJJJJJJ at CCFFFFFHFHHHJJJJHHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9421:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCCCAGCCTCATAGAGGAACTG
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9299:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACCAAACTTTTCAAACCATGT
++
+IJJHJIJJJHIJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9456:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATTTCGGAAATGCTAATCG
++
+IJJJJJJJJJJHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9347:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGCATAATAATGTATTTATTTG
++
+HJJJJJJJJIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9436:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTATGAGTGTGCGTCTCAC
++
+IGIIJJJJJJJJBCCFFFFFHHFHHJIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9384:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTCTGTTACACGCCGAGATC
++
+IGIHHHHHHFFFCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9328:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTGTTGCAGTCGGTGTTAT
++
+IEIIJJJJJHHHCCCFFFFFHHHHHJHGHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9477:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTGTGCTGCTTTCTCT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9580:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNTCTACTTGTTCTGGCCT
++
+HIIIIIIIIHII@@#4ADFDFHHHHII at GHII
+ at HWI-ST960:105:D10GVACXX:2:1101:9707:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTANGGAAATGTGCTATGGAC
++
+IJJA;FHIGJJJ@@#4ABDDHGHHHGHFGHII
+ at HWI-ST960:105:D10GVACXX:2:1101:9631:2165 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNGAATAATGCGTTTGTAT
++
+JIJJJJJJJJHHCC#4ADFFHHHHHIJJJHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9722:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANTCCACATGTTCAAGATT
++
+IGJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9563:2176 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCCTCGACACTGTTACTCCAC
++
+JJJJJ(=EHHHHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9614:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTGTCATATTTGCGATGTAT
++
+IJJJIHJJJJJJCCCFDFFFHHHHHIJGIGGHC
+ at HWI-ST960:105:D10GVACXX:2:1101:9676:2191 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTAAATCATTGTCTGAATT
++
+IJJIJJJJJHJJCCCFFFFFHHHHHJJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9526:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATCTTTTGTATTTTGCTGT
++
+JJJJJJJJJJJJCCCFFFFFHHHGHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9622:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGTACCTGTTATGCTTTAAA
++
+HJJIGHGGGIJJ@@@DDDEFDHHDHIIIJJIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:9597:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGTAGCTGTGGAATGAAAGT
++
+IHJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9507:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCTAGAGCTCTGATGAGTT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9613:2210 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTTTTCATAACTCATCCTACT
++
+IGIGIJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9741:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGAGACTGTATCCTTTAT
++
+JGJJJIJJIIJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9572:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATTAAAATTAGAACAAAT
++
+JJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9606:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTACATATAGTAGTGGAGGCCT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9767:2159 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAANCCATCGGCTCCTTCTTTC
++
+HJJJJJJJJGHHCC#4ADFFHHHHHJJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9910:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCNTTCTCTCTAGTTTGTTT
++
+IJIJJJJJJJJJCC#4ADDFHHHHHHIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9952:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAANACATCTTGTAGACTAAA
++
+IHJJJJJJJJJJCC#4BDFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9830:2163 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTNGTTTCGAAGATCAATAC
++
+IJJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9980:2165 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGNTTTTCTATATTCTTACT
++
+IHIJIGJIJJJJ@@#4=ADDDFFHHJGGHIIE
+ at HWI-ST960:105:D10GVACXX:2:1101:9995:2170 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGGGAACTCTTTTGGACC
++
+JJJFIIGGGHIJ@<@FFDDDFHHFHJIGEHIG
+ at HWI-ST960:105:D10GVACXX:2:1101:9998:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCTTATTAGTTTTAACTTC
++
+IHIIIIIIJJJJ@@@FFFDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9771:2192 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCCCTATAAATAAAAAACAGAC
++
+JGIGIJJHHHHHCCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9841:2194 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCTACACCAAACTCTGGTACAGT
++
+GCGGGHGJJIJJCCCFFFFFHHHHHJJFHIJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:9751:2194 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATTGTTGTAGGCTGTGGTCC
++
+JJJJJJJJJJJJBCCFFEFFHHHGHJJIJJIII
+ at HWI-ST960:105:D10GVACXX:2:1101:9885:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTTTGTGTAACTGTAAC
++
+IJJJIJJJJJJJ at CCFFFFFHHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9758:2211 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTGGCGACTTTCTACCGCAC
++
+IHHEHDEF at CEE@@@<DDADHHHDHIIIIIIEG
+ at HWI-ST960:105:D10GVACXX:2:1101:9838:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGTAGCTCCATGAACAAAT
++
+GGHEHIJJJIJJ at CCDFFFFFHGBFHIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9815:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAATAAACACAAAAGTTTT
++
+HIJIJJJJJJHHCBBFFFFFHHHHHJJJFHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9945:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAGGATTGGTTTGGTGGATTA
++
+HIJJJJIJJJJJB at CFFFFFHFHHHJCGIHJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:9878:2215 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGAAGCCAGATCAGAATCTT
++
+FGFHIHIIIIIIC@@FFFFFHHHDBFHGIGGHI
+ at HWI-ST960:105:D10GVACXX:2:1101:9912:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAAAGTTAATTTCTGTTTCT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9753:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTACCAAATAAGCTTAAGTC
++
+IJJJJJIIJJJJCCCFFFFFHHHHHJJJJJJHH
+ at HWI-ST960:105:D10GVACXX:2:1101:9999:2231 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTTTGTGATATCTGAAAAACAT
++
+IJJJGIJJJJJJCCCFDFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9840:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGATTTTTCCTTTGTTATC
++
+IJJJIJJJJJIJBBBFFFFFHHHHHJIIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:9928:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGCAAAGGCAAGGCTCTGCTG
++
+IJJIGJJGIJIICCCFFFFFHHHGHJJJIJGIE
+ at HWI-ST960:105:D10GVACXX:2:1101:9937:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGTCGGCTTAACTAAGGTGGA
++
+IIIEGGIHFHHH?@?BDDDFGHHGHHIEGACGH
+ at HWI-ST960:105:D10GVACXX:2:1101:9908:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAAGAACTCTGTAATTTCTGT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10110:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNTGAGTTTATATTTCGGA
++
+HHJHIJJJJJHHCC#4ADFDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10222:2164 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNAGACTTGGTCCCTAACAT
++
+JJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10062:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNCTGTACTCATTATCATCT
++
+JJJJJJJJJIJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10017:2167 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNCGAACAATGAACAATTGC
++
+HIIGIIIIIEHH?@#44BDBHH??FHBHIDDHI
+ at HWI-ST960:105:D10GVACXX:2:1101:10129:2182 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGTCCTTAATTCATTTAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10012:2196 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTGTATCCTTTCTCATTTA
++
+HIJJIJJIIIII at CCFFDDFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10236:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATATCACCATGTTCCAATTTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10124:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGTGTTGGCATGGGCCTCGA
++
+IJJJJIJJHHHHCC at DDFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:10018:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCGGTTGACTGGAATTATTTT
++
+IJJJJJJJHHGHCCCFFFFFHHGHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10188:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGTGATTGTTGGCAATAT
++
+HGIIIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10113:2246 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAGTGTAGAATGCATAC
++
+IGHIIJJJJJIJ@@CFFDEDHHGHHJJIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10362:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNGGACTGGAGTTTGACTCT
++
+IJJJJJJJIJJICC#4ADDFFGFHHGHEHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10363:2184 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGGATTCTTCGTTCAGGCCAT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10329:2196 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCAAGACTGCAACAACTTCTGC
++
+JGHIIIJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10309:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTTCTGTCATCTACATATGC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10373:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGTACTGTATTTGCTATTCCC
++
+IJJIHJJJJJJJBCBDFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10440:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTTTCTTTTTGTCGGCATC
++
+C7CFGEGIIHHE@@CFFFFFHHHHCFGHIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:10352:2213 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATTATCTCTGTTGATTGAT
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10470:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCCTAGAACTTGCTCAAAAAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10322:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTGGAACTCTTTCTTCTAA
++
+IJIFIJJJIJJJCCCFFFFFHGHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10300:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGAATCCATAGTCTTACCATGA
++
+ICHJJJJJJJJICCCFFFFFHHFHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10348:2237 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGACAAGTCGAATCTATT
++
+IIJJJJJIJIJJ@@CFFFFFHHFHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10434:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTATGTCGTTTCTTTGAACT
++
+GDFHIIJJJJII@@@FFDDAFFHHFIJGJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:10326:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGAGTTGATTGTGCAAACAA
++
+HGH>HH?GCEHG@?@DDBBDBHHFHGIIIGEHI
+ at HWI-ST960:105:D10GVACXX:2:1101:10530:2160 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCCTNGTGATCATGAAAAAAAA
++
+IHHGHHF at CFFFBC#4=DDFHHHGHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10666:2165 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTANCTCTCCAGTTTGTCATCT
++
+FHHIIJHEEHGI at C#4ADDFHHHHHJJGHGGHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10737:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNTGCTTATGTGCCCGTTTT
++
+JJJDHIJHHHHHCC#4ADDFHHGDHIJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10690:2167 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATNTAAATTTCGGAAATGCT
++
+JJJ>@GHGGHHHCC#4ADDFFHHGFGIGGIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10707:2172 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATTTAAATTCCTTCAAGT
++
+JJJJJJJJJJJJCB at FFFFFHHHHGJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10553:2176 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGTGTAGACTTAATTTTTT
++
+HIJGIHHHFFFF at CCFDFFFHHHHHIIJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10597:2193 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATGTACCGATGCATAGTC
++
+IJJJJJJJJJJJBBCFFFFEHHHHHJJJJJJHH
+ at HWI-ST960:105:D10GVACXX:2:1101:10566:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAGTTTTTGGATTGTAAATT
++
+IJJJJJJIJJJJCBCFDFFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10694:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTAATGTTAAATAACTC
++
+HIJIJJJJJJJJBB at FFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10746:2198 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTAACAGGGACAGTCGGGGGGT
++
+DDDDDDDDDDDDCCCFFFFFHHGHHIIJJJJD:
+ at HWI-ST960:105:D10GVACXX:2:1101:10522:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTCTGTACAGATATACTTTTT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10609:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTTGGCTTTTCTCTGCT
++
+GIJGIJJJJIJJCCCFFFFFHHHHHJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10672:2216 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGACTCGGATACGCTTCA
++
+IIJJJJJJJHHH at CCFFFFFHHHGHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10584:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGATGTTGAGGCTCAAAAGTT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJIII
+ at HWI-ST960:105:D10GVACXX:2:1101:10743:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTCGATAGAACTACAAAGAAT
++
+IJJJJJJJJJIJCCCFFFFFHHHHHJJJIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10653:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGTCCTTCGGATCACTCAAT
++
+IIJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10642:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGATTTTAAAGTGTTACAAG
++
+IJJGEIJIIJIJ at C@DDFFFHDDHHGGJIIJG
+ at HWI-ST960:105:D10GVACXX:2:1101:10627:2242 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACAAGTTGGTCTGGGTTGT
++
+IJJJJJJJJGHHB@@FFFFDFFDFFIIJFGHG
+ at HWI-ST960:105:D10GVACXX:2:1101:10734:2245 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAATCTGGGATGAACTCAC
++
+HEHIIGIJJJJJC at CFDFFFHHHHHIIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10579:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATCTTTAGTAGAACAAAATC
++
+IIJGIJIDIJJJ at CCFFFFFHFFFHIGHIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10596:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGTACTAATGGCGAAAGAAC
++
+IIJJJJJIIHHH at C@DFFFFHHHHHJJJGGGI
+ at HWI-ST960:105:D10GVACXX:2:1101:10939:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCANTAATTCCCTCTGATTCAT
++
+HHHIIJGIJIJJ@@#4ADDFFHHHFGHJJJGJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10984:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTACGATGTCTCTGTACTC
++
+IJJJJJIJJJJJCCCFFFFFHGHHHJJGHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10870:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATGGGTTCGACGTTAAAAAA
++
+JJHHHHHFFFFFBCCFFDDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10979:2195 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACTGAAATGAACCAAAACC
++
+HHIIIIIICEGHCCCFDFFFHGFHHJJJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:10780:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGTGGAACTACATTATC
++
+JJJJIJJJJJJJCCCFFDFFGHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10858:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTTGCGGATTATGCGTTTT
++
+HHHHHFFFFFFECCBFFFFFHHHHHJJJJFGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10924:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACAAAGTCGTTGTAGTATAG
++
+JJJJJJJJJIJJCCCFFFFDHHHHHHIJFHJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:10881:2211 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCATACTGTGTCTGCTTCTAT
++
+IGIIIIIGGHII@@<DDFFEHHHHGIIBHIGI
+ at HWI-ST960:105:D10GVACXX:2:1101:10798:2212 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCAATGTAGGTTGTTTTTGGAC
++
+IJJJJJJHHHHH at CCFFFFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10962:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATAGGAATCTGTAACTTT
++
+IGHIJIGIJJJJ@@@FFFFFHHHHGIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10898:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATTTCGGCTGTAGCATGT
++
+HIIEFHIIIIIJCBBFFFFFHHHHGEHIIIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10771:2225 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCGAGAATGATGAACCAATTAG
++
+IFGHHHIJIGJICCCFFFFFHGHHGJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10861:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTTAGACTCTTCGATTT
++
+JJJJIJIJJIJJC at CFFFFFHGHHHJJJJHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10883:2230 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAATGTTCTCTTTCTGATTT
++
+JJJIJJJJJJIJ at CCFFDFFHHGHHIJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10793:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAACTAATGGATGTATGAATAT
++
+HIJJJJJJJIIJCCCFFFFFHHGHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10996:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGTGTTGTTGACTCTGT
++
+IJJJIJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10908:2243 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCTGGAATGATGATAACGATTTT
++
+IIJJJJJHEHHHCCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:10822:2244 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTGTGTCTCAGAAAAAAAA
++
+HGHHFHHFFFFF at C@DDFDDHHGGFGGIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11036:2163 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNATACAAGGACTGATTTT
++
+IIJJJJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11235:2165 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGNGTCACTGTTGTTGTTCTT
++
+IIJJJJJJJJJJCC#4ADDFHHGHHJJJIJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11150:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTAGTAACTGAAAACGG
++
+JJJJJJJJIJJJCBCFFDFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11176:2178 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCTGTTGACCAAAAAAAAA
++
+FEFFFFFEEEEECCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11080:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTCCATAAGCTTTGATCACT
++
+JJJJJJJJIJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11039:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTAGTTAGTTGTTTTAAAAAA
++
+JJJJIFHJJGHH@<??DFFDHHDDHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11213:2190 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAATAAGAATAAGAATAAGA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11039:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGAGAAAATGAGCATTATTAT
++
+IIIGIJIIGHIJCC at FFFFFHHHHHJEEHEHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11145:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTTGTCTCTTAATCGGC
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:11168:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATCAATGCTGGTGCTAACTT
++
+HJJJJJJJJJJJCCCFFFFFHHGGDHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11088:2218 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAAGAACAAGAACACATTTAC
++
+IJJJJJIJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11184:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACATCCTTTCAAAACAAGTTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11073:2233 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAAGTCTGGAATAGCTTTT
++
+IJJJJJJJJJJJBBCFFDFFHHGGHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11102:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTTGTCGAACTTGTAAAAAA
++
+JJJIJJJHHHGHCCCFFEFFHHHHHJEHIJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11129:2239 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGGTTGGTTATACACCAAACTC
++
+IJJJJJIJJJJJB@=DFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11163:2245 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAATATGTCTGGCTTGTTT
++
+IJJJJJJGIJJJC at CFFFFFHHHHHJJJJJGIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11431:2161 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCCGNCTTTGACTTGAACCATAC
++
+HJIJIJJJJJJJCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11339:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNATAGGATATCAATAAAAC
++
+JIIJJJJJJJIJCC#4ADDFHHHHHJIIIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:11265:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNGGTCAATAGTAGATACTT
++
+IJJJJJJJIGHJ@@#4ABDFHHHGCGEIFIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11288:2167 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTANATCTTCTTTTCAAATTTC
++
+HJJJIJJJJJJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11397:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNCCAGACGGCAAGTGTGA
++
+JJJIJJJJHHHHCC#4ADDFHHHGHJJHIHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11321:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAATCTGTTTGGTTGTGGAA
++
+JGJJJJJJJJJHCCCFFFFEHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11427:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTCTTGGTAAAGGTTGAGT
++
+IJJJJJJIJJJJCCCFFFFFFHHHHICGHHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11305:2204 1:N:0: bcd:RPI2 seq:CACCGATGTATC
+CACCGATGTATCTACTGACCCCGAGGCTTTCGC
++
+HHHEFFCC;>>C@@@FDDBDFFHGGIIIIJHGH
+ at HWI-ST960:105:D10GVACXX:2:1101:11259:2205 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATATGTTTCGTAGAACTAT
++
+IIIJGIJJJIJJCCCFFFFFHHHHHIJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11401:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTAGAAAATGAACTATAAAT
++
+IJJIJJJJJHIJCCBFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11352:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTGAATAGTCGGGGTTACTT
++
+IJJJHHHHFDFFCCCFFFFFHHHHHJJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11437:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTGCGTCGTATGAGTAAAAG
++
+JJJIJJHHHHHF at CCFFFFFHHHHHIJGIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11258:2232 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAACCGAGTACTTTTGGTAGC
++
+HIJJHIJIJJJJ at BBFFFFDHHHHHJJJFHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11443:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGTAGTGTAGTGGTAAAA
++
+JGIJJJJJJJJJ at CCFFFFFHHHHHIJFHJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11272:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGTGCTTCAACGGCTCTGGT
++
+HIJJJJJJHHHH@@@DDFFFHGHFHIHGIIJH
+ at HWI-ST960:105:D10GVACXX:2:1101:11399:2247 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCATATGAACTACGTGTGGCTT
++
+JJJIJIJGIIJJCCCFFFFFHHHHHJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11695:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGNGCTTCCTAGAGCAAAGGA
++
+IJJJJJJJJJJJCC#4ADFFHHHHHJJJJJJHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11611:2171 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGGAGCTCAAGAACGGAAGAT
++
+IIJJJJJIJJHHCCCFFFFFGHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11736:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGAATACTGTGGTTGTTTTAG
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJHIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:11736:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGATACAATTTCGGTTTCGT
++
+JJJIJJJJJHHHC at CFFFFFHHHHHJHIJJIH
+ at HWI-ST960:105:D10GVACXX:2:1101:11623:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGTTTTGGGGTTTTAAACAT
++
+IJJJJJHHHHFFCCCDFFFFHHHFHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11724:2214 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTAGGACAGTTCATGTTTTT
++
+JJJJJJHHHHHFCCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11676:2225 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGCATCAAGCTGTAACCGAAC
++
+HJJJJJIJJHHHCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11707:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGGTATGAACTATGAACACAA
++
+IJJJJJJJJJJJCCBDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11640:2237 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTTAGACTCTTCGATTT
++
+HHJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11532:2244 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTAGTAATAGAGCTTGGAA
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11511:2247 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTGGAGATATTGGTTAACT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11573:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAACAATTCGGCTAGAAATTT
++
+IGIJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11924:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNCGTCGTTGTAGAATATC
++
+IIIJJJJJJJJJCC#4ADDFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:11984:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACNACCATCTCTGAACTCAT
++
+JJJJJJJJJJJJCC#4ADFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11822:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNATTTTTTCTTGCAACAC
++
+JJJJJJJHHHHHCC#4ADFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11773:2169 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTTCTTACTTCGGCCTGTT
++
+JJJIJJJJJHHHCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11943:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGATCATATGGACGTAACAT
++
+IJJJJJJJJHJHCCCFFFFFHHHHHJJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11759:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTGAGCTCTTCTTTTCTTA
++
+JJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11857:2196 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCTGTAGTAGGCTTGCATGC
++
+HHIIJJIIJJJICCCFFFFFHHHHHJJJJJJEH
+ at HWI-ST960:105:D10GVACXX:2:1101:11838:2200 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATCAATGTATTGTATCCG
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11790:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGAATTTCTGTAGACTATGT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11770:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGATGCGATCATACCAGCAC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11869:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGATGTTGGTTTGTAATAT
++
+IJJJJJJJJJJJBCCDFFFFHHFHHJIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11959:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTACTGTACACACAAACTTC
++
+JJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11892:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATAAAATGACTCTGAAAAA
++
+JJIJJJJJJJJJBCCFFFFFGHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:11899:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATAATGTAATAGTACTCACC
++
+IJJJJJJJJGHJ at BCFFFFDHHHHHHIJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12145:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGNTTCCGTTCCTGTTATCT
++
+III<==8=8 at DI?<#4=BDD:<CDDEBEE9<D
+ at HWI-ST960:105:D10GVACXX:2:1101:12229:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGNACTATTTGGGCTAAAAA
++
+JJJJJJJJJJJJCC#4BDFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12088:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTTTGTACAAATCCAAACCT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12143:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTCTGTCAACCTCTTCGGA
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12198:2193 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAGGGATGATGATTCAATTA
++
+HIJJIJJJJJJJCCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12019:2199 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATTGTTGAACTTAGAATCAA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12174:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTCTGTAGCTCTAGACCATTC
++
+JGIIJJJJJJJJ at CCFFFFFHHHHHJJJIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:12126:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATTCCCGTTGAGAGGATCAT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12157:2207 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGCTACTCTCCTCGTCTCCT
++
+JGJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12048:2210 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTACCACTCTTGCATTTGCAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12070:2217 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACAGAGCTCTGATTAAAGTG
++
+JJJJJJJJJJJJCCCFFFFFHHHGHJJJJJHI
+ at HWI-ST960:105:D10GVACXX:2:1101:12006:2219 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAGTTGAGCGGTTGAATAC
++
+IIJJJJJJJJHHCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12122:2230 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTCTGTATGCTTTTTTGGGAC
++
+==C@=@@A=777@@CFFDFDD<DFHGHIEHGEC
+ at HWI-ST960:105:D10GVACXX:2:1101:12107:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCACAACCTGTGAAAATCT
++
+HFHIGIJJJJIJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12066:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTGTGGATGATGAAGAGTTTT
++
+IIJJJJJJJIJJCCCFFFFFHHHGHJJIIGJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12166:2250 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGCAATATTCTAAAGAACTC
++
+JHJJJJJJJIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12124:2250 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGAATTTGGATTTGATCAGTA
++
+JJJJJJJJJJJJCBCFFFFFHHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12360:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNTAATTTCTATTTGGACT
++
+IJIJJJJJJJJ)CC#4ADDFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12436:2174 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATAAAGTTAGTTGGTGGTTG
++
+IJJJJJJJHHHHCCCFFFFFHHHHHJJGHIHII
+ at HWI-ST960:105:D10GVACXX:2:1101:12303:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATCTTTCTACTTTCATTAAC
++
+JJJJGJJJJJJJ at BBFFFFDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12490:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTTCAATTATGAGTTTTCCA
++
+HIJJJJJJJJJJCCCFFFFFHHHHHHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12308:2196 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTATAGTTAAAAGAGCACTAA
++
+JJJIJIG at HHIJ@@CFFFFFHHHHHJIJJIJG
+ at HWI-ST960:105:D10GVACXX:2:1101:12371:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGGTTTGGACAAAAAAAAAA
++
+C at CBBDDBC:ACCCCDFFFFHHHHHJJIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:12329:2218 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCCTTTGTCGCTAAGATTCGA
++
+JJJJJJJFHJIICCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12376:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGATCAAGTACAAGGGTTAT
++
+JJJJJJJJJJJJCCCFFFFFHFHFHJIIJEGHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12362:2226 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATATCGCATTAGCCCAGT
++
+IIIIIIIIIIII@@@DDDD?FFFFAGIFFFF9F
+ at HWI-ST960:105:D10GVACXX:2:1101:12430:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAATATACACTGAACTTTT
++
+JJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12484:2235 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAAGTTTCTATCAAAAAAA
++
+IJJJJJJJHHHHBBCFFFF;FHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12259:2237 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGCCTTGCTCTTCATTGGTTTC
++
+HIJIIGIGIIIJ at CCFFFFFHHHHHJJIIIJHH
+ at HWI-ST960:105:D10GVACXX:2:1101:12345:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCCCGATAAATAGAACGATAT
++
+JJJJJJJJJJHHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12290:2249 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGTCTGAAAAAAAAAAAA
++
+C at CBDBDBCDDCCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12543:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACNCGGTTGGTTTCCGTTAT
++
+JIJJJJJJJJHHCC#4ADDFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12590:2166 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNTGTATAAATAGTTTAAA
++
+IIIJJJJJJJJJCC#4BDDFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12617:2173 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAGTCTTATTGTATCTGT
++
+IHIJJJJJJJJJCBCFFDEFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12673:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGATTCAAATCGATCCCT
++
+IIJJJIJJJJJJC at BFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12575:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTATATTATGTGAAGTAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12730:2214 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGAGTCGATCGTAGAGTCT
++
+HJJJJJJIJJJJCBCFFFFFHHHHHJJIJHHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12674:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGTTTGATGTCTATGAT
++
+GFHIJGJIIJJJCB at FFFFFGGHHHJJIJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12690:2226 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCACTAGCTTCTACTTTGATAT
++
+?9D:CHGHC787@@@DAD8DBFHAHIIB?<F?I
+ at HWI-ST960:105:D10GVACXX:2:1101:12653:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTGTTTCTGTCTATGACTCC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12702:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGAGCCTTGTTTCTTATTTT
++
+IGIJIIJIJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12587:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTATTGATGATTCTATCTT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12614:2244 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCGACATTTGGTGTGAAATGC
++
+HJJJJJJJJIJHCCCFFFFFHHHHHIJJJJJHI
+ at HWI-ST960:105:D10GVACXX:2:1101:12898:2157 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNGTTAGTCGGACATCTTT
++
+HIIJJJJJHHFHCC#4ADDDFHHHGJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12779:2159 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNTAGGAATCTGTAACTTTT
++
+IJJJJJJJJGJJCC#4ADFFHHHHHIIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12941:2162 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAANCCATCGGCTCCTTCTTTC
++
+FGIIJGIGIJEHCC#4ADFFHHGHHJGIIIJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:12761:2162 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATNGAATTCAGAACTTTGTG
++
+HIIIIIIIIIII@@#4=BDDHHHHHIIIIIIG
+ at HWI-ST960:105:D10GVACXX:2:1101:12849:2171 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGCCCGACCTCGGACTGGGAAC
++
+HHHHHHFFFFFFCCCFFFFFHHHHHJJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12894:2184 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAAAGTAGTCTCATCTTATCAC
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12816:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTAAAGGCTTATTATCAAAA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12946:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTGATGAAATCTCATATTGA
++
+HJJJJJIIJJJJ@@BFFFFFHGGGHJJJJJJEI
+ at HWI-ST960:105:D10GVACXX:2:1101:12964:2189 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTAATATATGGACAATTTGGT
++
+HGIIIJJJJJJJCCCFFFFFHHGHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12914:2190 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTAACAACTTTTCATCT
++
+IIIIJJJJJJJJCBCFFEFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12899:2205 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGAAAGTAGCATCAAAACAA
++
+IJJHJIJJJJJJ at CCFFFFBFHFHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12750:2211 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATCTAGTACATACTCTGTTT
++
+JIJIJJJJJJIJCCCFFFEFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12962:2211 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTTTGTCTGAGTACGAACT
++
+JJJJJJIHJJJJCCCFFFFFHHHHFHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12876:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATAATTTTTAGTGAATAAC
++
+IJJJJJJJJIIJBBBFFFFFHHHHHHIHJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12908:2229 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTATGATGTAGAAGTATTG
++
+IJJJJJIJJJJJBCCFFFFDHBFHHJJFHIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:12760:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGGCTCTTGTTGTGAATC
++
+IIJIJIJJJIJJCCCFFFFFHHHHHJJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12926:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATTCAGCAGGATTATGCT
++
+GHJGEIJJIJJIC@@FFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12942:2239 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATTTCATTGTCTTGTCGGT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJHIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:12902:2246 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTATTTACATGTTGTTTGG
++
+IGIHIIIJJJJJCCCFFFFFHHHHGIJIJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:13152:2167 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGNAGAGCTGAAGAGCTTGAC
++
+FGIIIGIIAGII@@#4ADDDFHHFFIBIIIICH
+ at HWI-ST960:105:D10GVACXX:2:1101:13052:2176 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTTGTGACTGATCATTAG
++
+HHJJJIIJJJJJCCCFFFFFHHHHGJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13197:2180 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTTGTCACATTGTAAATCCC
++
+IJJJJJJJJJJJCBCFFFFFHHHHHIIIIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13235:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTAATAAGATTTTCTAGTTG
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJIGH
+ at HWI-ST960:105:D10GVACXX:2:1101:13099:2185 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATTCTCTGTATCTCTCGACTCTCT
++
+IJJJIIJJJGIJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13082:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTAGTATTATTATACACACTTG
++
+HJJIGIGGHHJJ@@@DDEFFHHFHDIJJIIIEI
+ at HWI-ST960:105:D10GVACXX:2:1101:13132:2192 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATAAATAAGCTTTGTTCA
++
+JJJGGIJJJJJJCCCFFFFFHHHHHJGGGHGI
+ at HWI-ST960:105:D10GVACXX:2:1101:13120:2196 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATTTGGACTGAGTCTGT
++
+JJJJJJJIIJJJB at BFFFFFHHHHHHIHIHJH
+ at HWI-ST960:105:D10GVACXX:2:1101:13177:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTACGTCGTTTTGTTCTCTC
++
+IIJJJJJJJJHHCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13060:2203 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATTAAAGAAGAACCCAAAAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13106:2213 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCGTAAACTCATAAATAAAT
++
+IJJIIJJJJJJJCCCDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13215:2231 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTGTGTTGGCGTTTTATCT
++
+JJJJJJJJHHHHBCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13012:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAATGCCCATTAATCGTGGT
++
+IJJJJGIIJJJJCCCFFFFFHHHHHJJJGHJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13172:2240 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTGCCTATTTATTTGCTGTC
++
+HGJJIIJJJJJJCBCFFFFFHHHHHJHIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13045:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTCTGAGATTGTAGAACAAT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13155:2249 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAAAAGGTCAAGGTTGGCAAG
++
+IJJJJJJJJJJJBCCFFFFDFHHHHFHJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13431:2158 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGANGTTAGAACTCGAATCAG
++
+GGJJJCGCHIJJCC#4ADDDHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:13336:2159 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNATCACATCTCCCTCTTGA
++
+IJJJJJJJJIJJCC#4ADFFHHHHHJJJJJIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:13413:2164 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTANCAGTTGATAAATGAATAA
++
+IGHGIIIIIIII@@#4ADADFHHHHGHIIIGII
+ at HWI-ST960:105:D10GVACXX:2:1101:13458:2176 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGTAATGTAGTCTTTTAT
++
+IIJJIJIJJJJJCCCFDFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13473:2178 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGTTAGGACAGTTC
++
+GHHGBDHII=BF@@@FFDFFHHHHH
+ at HWI-ST960:105:D10GVACXX:2:1101:13435:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGAATAATGAACTTTGATTAA
++
+IJJJJJIJJGIJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13272:2183 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAAATCTCCCTTTTTTTGT
++
+JGIJJHHHHHHFCBBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13312:2186 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTGTGTAGAATCTGCTTATAA
++
+HIJIJJJJJIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13253:2186 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATAGTTTGGACGTTGGTACACGA
++
+IIIGIEEHGHHG@@?DDDFFFHHGABFBHIII
+ at HWI-ST960:105:D10GVACXX:2:1101:13363:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGCTAAGGAAGTAAAAGCCAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHIJJIIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13404:2208 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACGACATTGCATTGTATGTTG
++
+IJJJJJJJJIIICCCFFFFFHHHHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13366:2209 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATATGTTGTCGGTTCTAGT
++
+FAFIIEHGGHAG@@@F=DFFBFFFHHIAHE<C
+ at HWI-ST960:105:D10GVACXX:2:1101:13340:2212 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATATGTTTCGTAGAACTAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13430:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGTTTTGGATACATAAAC
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13478:2222 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATGGTGATGAAACGAATATTT
++
+IJJIJJIJJJHHBCCFDFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13253:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATGGGTCTCTAGATGCTTT
++
+IJJJJJJJJJJJCCCFFFDFHHHGHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13357:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTCTTTGGTGCCCATGCAA
++
+IIIIIIIIIIII@@@??DAB>F?DFACB?C?E
+ at HWI-ST960:105:D10GVACXX:2:1101:13444:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTTACGATTCATGGTTCTGT
++
+IHICBFHGIIII<@@FFBDDHDDHHGEHHBG?A
+ at HWI-ST960:105:D10GVACXX:2:1101:13383:2241 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAATCTCTACTGTTTGTTCT
++
+FHIGIIGAGEHICC at FFFFFHHHGFHIGHCFEE
+ at HWI-ST960:105:D10GVACXX:2:1101:13323:2243 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTCTCAATACTTTCTTCCTC
++
+HJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13571:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNTGTAGAATAAAGCTCTCT
++
+IJJIJIIJJJJJCB#4ADDDHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13621:2162 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNATATACACTGAACTTTT
++
+JIJJJJJJJIJJCB#4ADFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13664:2164 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTTNCGTCGACTATGATTAAT
++
+JJJJJJJGIJJJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13556:2177 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTTGTATAAACGGAATTTCT
++
+HIJIJJJJJIJJCCCFFFFFHHHGHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13647:2177 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCTTGATCACGAACATAATATT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13575:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGCTTGCAAGTTCTCTCTGAA
++
+JJJJJJJJJJIJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13528:2185 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAGTATGTTTGCGGATTAT
++
+IIJJJJJJJJJHB at BFDFFFHHHHHJJGIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13614:2188 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTCTTTCGAGTTTTATGAT
++
+JJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:13510:2190 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTGTCTTTCTCCTTCTCTTCT
++
+JGIJJJJIJJJJCCCDFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13692:2200 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGCTTTGCTTAATTCATTG
++
+HIJJJJIJJJJJC at BFFFFFHHHHHJJJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:13666:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCAAATTTCAATGAGATTGT
++
+IJJIJJJJJJJJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13720:2208 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATCAGAGTGACTCAACCAAA
++
+IJJIJIIJJJJJBCCFFFFDHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13526:2209 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGCCCTTTGTCGCTAAGATTC
++
+JJJFJJJJIGFHCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13506:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATAATGTGTGTGGGACTTA
++
+FHIIIIIIIIII@@@DDDD;CCFF;GFHHAEH
+ at HWI-ST960:105:D10GVACXX:2:1101:13623:2212 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATGGCAATCGTCTCTCTAT
++
+IIJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13684:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGGTCCCCACTGAGAACT
++
+IJJJIJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13646:2224 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTGTTATAGATTCCTCCT
++
+IJJJJJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13506:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGGAACAAGGATTACAAGAA
++
+HIJJJJJJJJJJC at CFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13700:2234 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATAAGCTGAGCGAATATTAG
++
+IJJIJIJJHHHHCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13525:2242 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTGTTATTGGCCCAAGTAGA
++
+HDHIIIJJIJGI at CCFFFFFHFFHHJIGCGGH
+ at HWI-ST960:105:D10GVACXX:2:1101:13744:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATGCTCTTTTAATGTGCAT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13514:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTTTCAAACTGAGCAAAAAT
++
+F=FDGIHGHGHG@@@DFDBDFHHDD:ACFHGHI
+ at HWI-ST960:105:D10GVACXX:2:1101:13631:2249 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGTTAATGTCTCTGAAACAA
++
+IJJIJJJJJJJJCCBDFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13611:2250 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAACGTAGAAACTCTTGGTAA
++
+JJJJJIJJJJJJCCCFFFFFHHHHHJJJJHIH
+ at HWI-ST960:105:D10GVACXX:2:1101:13895:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNATGTTGGCAAAGAAACAC
++
+IJJGIGHHJHHH@@#4ADDDHHHHFJGHIJIHH
+ at HWI-ST960:105:D10GVACXX:2:1101:13803:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACNGTGTTGGCGTTTTATC
++
+IGIJJIJJJJHHCC#4ADDFHHHHHIJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13821:2166 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTNCGTTCTCTGTTGATGAC
++
+F=F;FADEEHGC@@#4=DDDFFHHFIF>C?EF
+ at HWI-ST960:105:D10GVACXX:2:1101:13873:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGGGGTCCCAGTTCCGAACCC
++
+HHHFFFFFFFEECCCFFDFFGHHHHJJJJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13832:2175 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTGCCTTTTTCTCTTCT
++
+HJJJJJIJJJJJC at CFFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13756:2181 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCACAGTCGGCTTACCCGGGGAC
++
+DCFFEEEEDDDD at CCFFFFFHHHHHJJIIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13888:2181 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGAGAGATTTCGTAAAAAAC
++
+IJJJJJJJHHHHCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13863:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTGGTTGGTGTAAAAAAAA
++
+HHHFFFFFEEEEBCCFFDFFHDFFHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13978:2187 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGACTCTGTAGCTTTACTT
++
+HHIHJJIJIIJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13770:2198 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCAACATATGTTTCATAATGT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13874:2204 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATAAAAGTTGTCGTAGCATAA
++
+IJJIJJJJJJJH at CCFFFFDHHHHHJJJJJJHH
+ at HWI-ST960:105:D10GVACXX:2:1101:13985:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTCTTGACTTGCCTCCTTACC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13941:2214 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTATTTATATATTTGATGTTT
++
+JJJJJJJHIJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:13963:2214 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTCTGTCTATTTCGTTAAATC
++
+JJJJJJJJJJJJCCBFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:13752:2222 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTTGTCAATTGTCATATTTGC
++
+JJJIIJJJJJJJCCCFFFFFHHHGHJJJJJJHI
+ at HWI-ST960:105:D10GVACXX:2:1101:13859:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTCTGTTTCAATGTCCCTTGC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ<4
+ at HWI-ST960:105:D10GVACXX:2:1101:13939:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGAGTCAAGACTCAAGACTAT
++
+IJJJJJJJJJJJBCCFDFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14150:2157 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACNGTTGTAGTCTCTGTGTAT
++
+HIJIJJJJJJJJCC#4ADDFHHHHHJJJHHHHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14171:2160 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCGNATGAACTCTGGTTTAGTT
++
+HHJHJJJJIJJICC#4ADFFHHHHHJGHJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14041:2163 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTANATATGTAGTCTTATGTCT
++
+IJJHJJJJJJJJCC#4ADFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14084:2164 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCTCNGATGATGATCAAATCAT
++
+HFHIFIJIIJIJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14180:2173 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCACAACAGCATATTTATAAA
++
+FBF at GGIIGGHI@@@FFFFDHHBDHIJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14103:2174 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAACAAAAGTGGCTGTAGTTT
++
+JJJJJJJJJJJJBCCFFFFFFHHHHJIJJGJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14196:2181 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAGGTGTTACTGTGGATTTC
++
+G4BFFHEHIHGE:==DD2BDHHBHDIEE at DGHE
+ at HWI-ST960:105:D10GVACXX:2:1101:14128:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATGTAGTAGCAACTCTT
++
+JIJJJJJJJJJJCBCFFFFFGHHHGJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14033:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTGGTAACTGGACTCTGAT
++
+HGIJJJJIJJJJC at CFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14074:2199 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTAATACACTTTCCCTTACAT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14019:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTCTCTGTGATTCTCTTTTTA
++
+HDGFHJIGJIGICCCFFFFFHHHHHIJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:14232:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAGCTGGAAACTTTGAGCTT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14143:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTGGCACACTAAGCTG
++
+JGJJJJJJJJJJ at CCFFFFFHHHHHJJJJJI3
+ at HWI-ST960:105:D10GVACXX:2:1101:14121:2210 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTAGTAGCATGTGAATTTA
++
+IIIIIIIIIIII@??DDAD;?DHD?DDHGEGC
+ at HWI-ST960:105:D10GVACXX:2:1101:14168:2213 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATTCTATCGGATTCTCAAC
++
+IGJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14102:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTATTTGATCTACATTGTAT
++
+HGHGIJIJIIGIBCBFFFFFGHHGHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14036:2225 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCCCGAACTCTACGTAGAAAT
++
+IJJJJJJGJJJHCCCFFFFFHHHHHJHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14209:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTACTCAACACTCTCTTCTT
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14087:2229 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGAGTTCTTAGCCATTGCAT
++
+IGIJJJJJJJJJCCCFDFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14127:2230 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCACTCTGGATTCAATTTGGAT
++
+JJJGIJJJJJIJ at CCFFFFDHHHHHJJIIJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:14273:2157 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNCTCGTCGCTTGTGGCTC
++
+H at EHIHHHHHHHCC#4ADFDHHHHHJFHIHIH
+ at HWI-ST960:105:D10GVACXX:2:1101:14385:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCGNGACAAAAGAACTGGACTC
++
+IJJJJJJJJJJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14449:2160 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCNCTGTCACAATGGTTAAAC
++
+IJJJJJJJJIJJCC#4ADDDHFHHHJIGIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14408:2163 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNTGTTTTTCCCAAAATAC
++
+HHJJJJJJJJJJCC#4ABDFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:14427:2163 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTNACAGAAGATAGAGAGCAC
++
+HJJJJIJJJJJJCC#4ADFFGHHHHJJIIJJGI
+ at HWI-ST960:105:D10GVACXX:2:1101:14472:2172 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATAACGATCCTCTGTGTCTCTCTCGATCGA
++
+HHJJJIJJJJJHCCCFFFFFHHHHHJJJJJJ33
+ at HWI-ST960:105:D10GVACXX:2:1101:14402:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATAAAGTGGTCTAGTGGTT
++
+IJJJJJJJJJJJCCCFFFFDHHHHHJIEGIHG
+ at HWI-ST960:105:D10GVACXX:2:1101:14443:2185 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTTTACTGTCCTCTGATCAG
++
+JJJIIJJJJJJJCCCFFFFFHHHHHJJJJJJ3
+ at HWI-ST960:105:D10GVACXX:2:1101:14420:2208 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATGTATATATAAGAGTCAT
++
+IJJHJJJJJJJJCBCFFDFFGHHHHJJJJHHGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14467:2209 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGAAACTGTACTTGAGATTA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14311:2215 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTCTTTATGGCTCTAGTACAA
++
+JIJJJJJIJJJJCCCFFFFFHHHHHJJJIIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14442:2218 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAAAATGTCGTTGTAGTATAG
++
+JJJJJJJJJJJJCCCFFFFEHHHHHHJJIIJGI
+ at HWI-ST960:105:D10GVACXX:2:1101:14388:2226 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATTCCAGTTGATTGAGGTC
++
+ICHIHIFHIJJJCCCFFFFFHHHHHJGHJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:14404:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTGTTGGCTATGATGTTAT
++
+HIIJIJJJJJJJCCBFFFFFHHHHHIIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14361:2234 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAAATTATGATGGAAGATTTGT
++
+HHJJJIJJJJJJCCCFFFFFHHHHGJJHJJJ34
+ at HWI-ST960:105:D10GVACXX:2:1101:14303:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACATTTAGGCTCAGTGGGA
++
+JIJJJJJJJIJJCCCFFFFFHHHHHJGHIIG
+ at HWI-ST960:105:D10GVACXX:2:1101:14342:2235 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGCTCTTCAACCTTAGAAGA
++
+IGJJJJJJJJJICCCFFFFFHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14263:2238 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTACTTTCTCGTGCTAACTC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14722:2164 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNGTTGGCCTTAAAAAAAA
++
+EEHHEHFFFFFECC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14632:2164 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGNTGATTCTCCTTAGATCTG
++
+FHIIJJJJIIJICC#4ADDFHHHGHJJJJJJGI
+ at HWI-ST960:105:D10GVACXX:2:1101:14512:2169 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGCAATCCCTCTGTTTCCTAA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14677:2181 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGACAGAAGATAGAGAGCAC
++
+IIJJJJJJJJJJCCCFFFFFHHHHHJJJJIIGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14738:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATGTTCATGTCTAAATTCG
++
+HHJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ3
+ at HWI-ST960:105:D10GVACXX:2:1101:14684:2203 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAGCCGGAGACAGGAGAGGTG
++
+HHHHFFFFEEEECCCFFFFFHHHHHJJJJJJ*?
+ at HWI-ST960:105:D10GVACXX:2:1101:14526:2204 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCACATAGACTAATCTTATAAT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14580:2206 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAATAAGGTATCAGGTTTTA
++
+IIJIJJJJJJJJCCCFFFFFFFHHHJJEHIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14592:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTTATAGGGAGAAGAAGAGGC
++
+HDHIJIJJJJHHCCCFFFFFHHHGHJJJIJJ34
+ at HWI-ST960:105:D10GVACXX:2:1101:14659:2235 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATTGGTGCCTGTAGGTCAG
++
+IHJJJJJIJJJJCCCFFFFFHHHHHJJJFHI3
+ at HWI-ST960:105:D10GVACXX:2:1101:14548:2237 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCAATTTTATGTCGTTTCTTTG
++
+JJJIIJJJJJJJCCCFFFFFHHHHHIJJJJJ<
+ at HWI-ST960:105:D10GVACXX:2:1101:14792:2167 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTANGGTTTGGCTGTTAACAC
++
+FBGE>FHIJJHHB@#4ABDFHHHHHIJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14962:2168 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATCCACACTAAGTCCAAGC
++
+HIJJJJJJJJJJCCCFFFFFHHHHHHIJIJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:14851:2171 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTATTTGTAGCAATTCTGTTTT
++
+IJJJJJJJIIJICCCFFFFFHHHHHJJIIFHHJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14982:2172 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCGTAATCTGGGATGAACTCACT
++
+JJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14927:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTCTTGTTTAGAAGCAAGAA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14906:2195 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGCCAACTCTGTTTCTTCTTCT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJIJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14858:2195 1:N:0: bcd:RPI3 seq:CACTTAGGCATC
+CACTTAGGCATCATTCGTTTCAATGTCAATCTC
++
+IIIHGIHGIJJJ at BCFFDEFHHHHHIJJIJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:14936:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGCCAATGTTGTAGAACTAT
++
+HIIIIIIIIIII@@CFFDFFHDAFFBHIG at H@
+ at HWI-ST960:105:D10GVACXX:2:1101:14780:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTGTGAATCCTTTTCCATT
++
+IGJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14808:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATGAAGAGGCTGTTTCTAC
++
+IGIJJJJJJJJJCCCFFFFFGHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14828:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGTATGTTGTTATTTGATAA
++
+HGIGIGIJHIJI at CCDFFFFHHHHHJJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14929:2217 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAACACTCTTATCAAAAAAAA
++
+IJHHHHFFFFEECCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:14844:2223 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCATACATCTTTGCAGAACTCAT
++
+HIIC=CGCFGIH at C@FFFDFHGFDFD<ABBDIF
+ at HWI-ST960:105:D10GVACXX:2:1101:14988:2233 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGCTTAGACTTGGTAGTTGT
++
+HHJJJJJJJJJJCCCFFFFFHHHHHEHIHIIG
+ at HWI-ST960:105:D10GVACXX:2:1101:14821:2236 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGTGTACTTGTGGACAAGGT
++
+FFHIHIJGHIJJ@@=DDEFFHHHHGJJJJJI>
+ at HWI-ST960:105:D10GVACXX:2:1101:14761:2243 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTTGTAGTCGTAAATATCT
++
+IHJJIJJJJIJJCCCFFFFFHHHHHJIJIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:15012:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAANTTCTCCCATCAGTTACAA
++
+IIJJJJJJJJJJC@#4ADDFHHFHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15055:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAGNAACTGTATCTATGTCGT
++
+JJJJJJJJJJJJCC#4ADFFHHGHHJJJIIJG
+ at HWI-ST960:105:D10GVACXX:2:1101:15030:2168 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTCTGTTACACGCCGAGATC
++
+JJJHHHFFFFFECCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15079:2180 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCAGGGCAAGCACAACATAT
++
+JJJJJJJJJJJJCCCFFFFFHHGHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15143:2186 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCATCTTTTTCATCCCAATCTGT
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ<3
+ at HWI-ST960:105:D10GVACXX:2:1101:15178:2193 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAGTGATGAACCTTTTGAACC
++
+IJJJJIJJJJJJCC at FFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15053:2195 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATCCAGTCTCATCGCTGTTG
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJIJJJJEI
+ at HWI-ST960:105:D10GVACXX:2:1101:15025:2214 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCGTATGTAAAGGTTTACTCTTT
++
+JJJJJJJHIJJJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15186:2216 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCAGAGCAAGTCGAAATCTGTT
++
+JJJJGJJJJJJJCCCFFFFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15065:2224 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTGTGCTGGGAACTATTTGAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15143:2225 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATGAAAACTTCTTGAGTTAT
++
+IIJJJIJIJJJJCCCFFFFFHHHHHJJJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15008:2227 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTTCTTGGGACTTGATTTTT
++
+IGIHIJHGHHFF#CCFFFFFHFHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15207:2236 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTAGTGTGTAATGTTATTGG
++
+IIJIJJJJJJJJBCCFFEFDHHHHHJHJJJJ34
+ at HWI-ST960:105:D10GVACXX:2:1101:15000:2247 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTGGTCATGTTTGCTATTTG
++
+FFF;FF at G3=DC at CCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15342:2165 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCCGNATCTGGATTTAAGATAA
++
+IGIIIJJJJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15274:2198 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCATCTGTCTAAAGTTTGTTCT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15308:2216 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGTAATTTAGCATGTTGCAAA
++
+IJJIIJJJIIJICCBDFFFFHHHHHJJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:15475:2222 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCTGTAGTTGTATTTCAAC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15291:2232 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGTTGTTAGCTATCACT
++
+IHJJJJJJJJJJC at CFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15347:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGAACTCTGACCAATGAACTT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15331:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTGTTATATATTACTGACTAC
++
+HJJJJIGIJJJJCCCFFFFFGHHHHJJJJJJDI
+ at HWI-ST960:105:D10GVACXX:2:1101:15450:2248 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGTTTTGTCCCTTTGTATTT
++
+JJJJJJJJJJJJCCBFFFFFHHHHHJJHIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15610:2159 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGNTCTGATTTCAATTTTTGC
++
+JJJJJJJJJIJJCC#4ADFFHHHHHJJJJJI33
+ at HWI-ST960:105:D10GVACXX:2:1101:15730:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAGNCTGCTACAACAAAAAAAA
++
+HHH>DFDDCEEDCC#4ADFFHHHHHJJJJJJIH
+ at HWI-ST960:105:D10GVACXX:2:1101:15650:2166 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNTTGGCAGCGTATCTTTTC
++
+HIJJJJJJJJHHCC#4ADFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15745:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNATGTCATTAATGAAAACT
++
+HIJJJJJJJJJJ@@#4ADDFGHHHFJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15691:2179 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTACTAGTCTCGTATTAACTA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:15591:2179 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTTGCTTATGTGCCCGTTTT
++
+IIJJJJJJHHHHCCCFFFFFHHHGHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15612:2183 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATATCCTATGTCTAAAAAAA
++
+IIJIJJJHHHHHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15528:2190 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATTTCGGATCTTGGCTACTAA
++
+IJJIJJJJHHHHCCCFFFFFHHHHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15503:2198 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAATCTAAAGGGATTTGGTGT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJHII
+ at HWI-ST960:105:D10GVACXX:2:1101:15541:2201 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CAAACTTGAATCGTCTGTAGCTCTAGACCATTC
++
+IIIIJJGIGIJJ at CCFFDEFHHFHHJIJGGIJH
+ at HWI-ST960:105:D10GVACXX:2:1101:15700:2204 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTAAATTCTCTTCCTTTGGT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:15649:2217 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTAATGTGATGGTTTCTTCAA
++
+IIJJJJJJJJJJCCCFFDFFHHHFHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15573:2222 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATAGCTAGTCATAACTCTTT
++
+IJIJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15731:2236 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATATGTTTCGTAGAACTAT
++
+JIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15639:2244 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTTTTACGGAGTACAAGAGAT
++
+JJJJJJJJJJJJCCCFFFFFHHHFHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15900:2158 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGCNAGATGATGGTCATTATAA
++
+IJJJJJJJJJJJCC#4ADFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15963:2161 1:N:0: bcd:RPI1 seq:CACATCACGATC
+CACATCACGATCATNTGTAAATATACCACGAAT
++
+C=GI@=CHC7=E@@#4==BDA?DFHG@<A<CCG
+ at HWI-ST960:105:D10GVACXX:2:1101:15856:2161 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTCNGATGATGATCAAATCAT
++
+JJJIJJJJJJJJCC#4ADFFHHHHHJJJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:15824:2174 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATATGTCTGTACACAATCT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15924:2187 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGAAAATGTTGTGAACTG
++
+IIJJJJJJJJJJCBCFFFFFHHHHHJIJJJJGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15857:2189 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTAGGTTTAGAGCTAAAAAA
++
+IJJGJJJJJHHHCCCFFFDFHHHHHJJJJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:15755:2216 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATACTACTAATACATTTT
++
+JGIIIJJJJJJJCBCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15970:2220 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCCATGACTGAAGTTGTTTGTC
++
+IJJJJJJJJJIJCCCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15886:2223 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGTTTTATTTCTTATTCAA
++
+IJJGJJJJIJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:15866:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGTGTTGGCGTTTTATCTG
++
+IIJJJJJJJJJHBCCDDFFFHHHHHJJJJJJ2
+ at HWI-ST960:105:D10GVACXX:2:1101:15925:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTTTTGTTGGATTGTTTTGCT
++
+FFHBHJGIEA at C@@@FFEDDHGFBHBHIJGGGI
+ at HWI-ST960:105:D10GVACXX:2:1101:15938:2248 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTCTTGTCCGTTACATTTGCC
++
+IGIIJJJJJJJJ at CCFFFFFHFHFHJJJJJJG
+ at HWI-ST960:105:D10GVACXX:2:1101:16121:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTNATATATTCATGCATATT
++
+IIJJJJJIJJJJCC#4ADFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16240:2167 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTNAGTAGTAGTAATGTCAAC
++
+IIIIIECCFHII?=#4=DDDCFFFFHGHEEI at H
+ at HWI-ST960:105:D10GVACXX:2:1101:16016:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTGTGTTGGCGTTTTATCTG
++
+HIJJJJJJJJHHCCCFFFFFHHGHFIJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16084:2189 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAAATGTGAAATCTTAAAATC
++
+IIIC?==BFHII@@@DD:=DFDDB?ECDFGED
+ at HWI-ST960:105:D10GVACXX:2:1101:16060:2193 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCGAGAATGATGAACCAATTAC
++
+HJIIGJJJJJJJCCCFFFFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16022:2204 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCATGAGATACTGAATTCAAGC
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJ33
+ at HWI-ST960:105:D10GVACXX:2:1101:16131:2207 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTATGTATGATCATATTTTT
++
+HIJJIJJJJJJJCB at FFEFFHHHHHJJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16147:2216 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCATTCAAATCAGAGGCTTGTTA
++
+FHIGIJIJIIFHCCCFFFFFHHHGHJJJJIFEH
+ at HWI-ST960:105:D10GVACXX:2:1101:16171:2218 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTCTTCTTCGTTTGGCTATTTT
++
+IJJJJJJJJHHHCCCFFFFFHHHHHJJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16114:2220 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGCAGCACTTGTCTGACCCAT
++
+JJJJJJJJJIJJCCCFFFFFHHHFHJJJJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:16083:2223 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATGTAGAGAATCGATTTAT
++
+JJJJJJJJJIJJCCCFFFFFHHHHHJJJJIJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16174:2241 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACTTTGAGAACTAAAAAAAA
++
+=7=7=E=7@###@@@DDDDDFFFFFIIIIIID
+ at HWI-ST960:105:D10GVACXX:2:1101:16002:2242 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGGAGTTTTGGTTAGGTTGT
++
+GHJJJJJJJJJJBCCDFDDFHHHFHIJJEHI:
+ at HWI-ST960:105:D10GVACXX:2:1101:16214:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTGGTAGATGATAACAAATC
++
+HJJIJJJJIJIJCCCFFDFFHHHGHJJJJJJII
+ at HWI-ST960:105:D10GVACXX:2:1101:16126:2245 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTGTTGTTGTTGTTGTTGT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHIIJIIJ;
+ at HWI-ST960:105:D10GVACXX:2:1101:16191:2247 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCTGGAGAACTTGGCAACTCAC
++
+IIIB=FHIIIII@@CFFFFDA?FFAHIIGEE@
+ at HWI-ST960:105:D10GVACXX:2:1101:16292:2160 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGCNCTTGTTAGTAGTTTCTG
++
+IGIJJJJJJIJJC@#4ADDDDHHFHJIIIJJ3
+ at HWI-ST960:105:D10GVACXX:2:1101:16335:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTANTCCACTTGCTTATCATC
++
+HIIGHIJJJJJJCC#4ADFFHHHHHJJJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16262:2167 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCCANTTGAGGAACTATTGTTT
++
+C=CFHEEGHICA7;#44ABDHDDHDGG at EA@>
+ at HWI-ST960:105:D10GVACXX:2:1101:16438:2169 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATGTTCGGTTGTGGGATTCT
++
+HIJJJJJJHHHH at BCDFFFFHHHHHJJGJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16355:2177 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTTAGACTCTTCGATTT
++
+HGHJJIJJIJIJCCCFFEFFHHHHHJJJJJJGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16306:2182 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTACCTACTCGTCGTACATTTT
++
+HJJJJJJJHHHHCCCFFFFFHHHHHIJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16427:2183 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGTTGATTTTAATGGTTACTGT
++
+BFHIJGHIEHII at CCFFFFFHHHHHJFHGHIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16368:2191 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATAAAAACTCTGAATTTAAT
++
+IJJJJIJJIJJJCCCFFFFFHHHHHJJJJIJC
+ at HWI-ST960:105:D10GVACXX:2:1101:16496:2191 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTTCTGTTGAACCTCTTG
++
+HHJIIIIJJJIJCCCFFFFFHHHHHJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16268:2194 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTCAAACCATTGAGACAGCTT
++
+HIJJJJJIJJJJCC at FFFFFHHHHHJJJJJJGI
+ at HWI-ST960:105:D10GVACXX:2:1101:16478:2197 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCCTGTGAAACTGCGAATGGCT
++
+F=FHIHJGIJJHCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16378:2215 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTACGTTATTTAAAATCCTC
++
+IJIJJJJIJJIJCBBFFDFFHHHHHIJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16273:2227 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTTATGTGACTGGAGAGA
++
+IIJJJIJJJJJJCCCFFFFEHHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16350:2227 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTGTGGCTCAGAACCACCAC
++
+IIJHIJJJJHHHCCCDFFFFHHHHGJJJIJII
+ at HWI-ST960:105:D10GVACXX:2:1101:16328:2230 1:N:0: bcd:RPI4 seq:CACTGACCAATC
+CACTGACCAATCACTGATCGCGTCGTGTTAC
++
+HIJJJHHHHHFF at BCFFFFFGHHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16408:2232 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTCGAACAATGAACAATTGC
++
+HIJJJJJJIJJHCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16369:2234 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTACATTGTGAAATGATATTTC
++
+HGEGGIJGIJJJ at CCFFFFBHHHHFGIIJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16305:2250 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCAAACCTGTATCTGTGTAACT
++
+IIJGIJJJIJJJCCCFFFFFHHHGHGJIGHIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16684:2159 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTNTTCGGATTTGAACAGA
++
+JIIJJIJJJJIJCC#4ADFFGGHHHJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16513:2160 1:N:0: bcd:RPI5 seq:CACACAGTGATC
+CACACAGTGATCTGNTATGTTGGTTAAGACTTT
++
+JIIIIII at C=DH at C#4ADDDFHHFHIJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16553:2167 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACNGTTTTGCTAAAATATTC
++
+HAHGIJJIJJIJCC#4ADDFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16647:2170 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTAATTGAATATCTTCAATGT
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16734:2178 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTACGAATTCTAAATTTTAT
++
+HIJIJJJJJJJJBBBDFFDDHHHHHJJJJIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16682:2192 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTATCAATAAGCGGAGGAAAAG
++
+HIIGHGGHHHFF@@@FFFFFHHAFFHDDHIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:16516:2203 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGAGAGTTCGAATCTGTCAGGC
++
+GIJJJJJJJJJJCCCFFEFFHHHHHJJGIJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16583:2204 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATCGGCGCTTGTTCACCTCTC
++
+HIHHHHHFFFFFCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16633:2220 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCATTGTATTTTAACAGCACTC
++
+JJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16696:2231 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTAATGTAGTCTTTTAT
++
+GGHIIIJJIIJJ at C@DDDDFHFFHDBGIIIIH
+ at HWI-ST960:105:D10GVACXX:2:1101:16666:2233 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTAACACTTGGTTCCGTTTC
++
+IJJJJJJJJJIJCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16730:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCCTATAAATCGTCTCATGAA
++
+JJJGIJJJJJJJCCCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16561:2240 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATAACCCTTTCCAGGCCATGT
++
+CDHIGHIIIGCD@@CFDEFFHHDHHGFBHEGGJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16708:2243 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCACCATTGTCTGAATAAAAAG
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17000:2158 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTNATCCTCGTTATATTTGT
++
+FFFIIIIIIIFI==#4=2ADFAFFF at FIIE@C
+ at HWI-ST960:105:D10GVACXX:2:1101:16900:2161 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGANCAAACCGACACTCGGGAT
++
+HHHHFFFFFFEECC#4ADFFHHHHHJJJIJJHI
+ at HWI-ST960:105:D10GVACXX:2:1101:16800:2165 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATNTATTTGGGGTTATTTGCA
++
+HIJJJJJJJJJHCC#4ADDFGHHHFHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16874:2165 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCTTNGTTGAACGACAAAATAA
++
+GHIHEDEHHGFF at C#4=BBDHFHHGGIGJEGG
+ at HWI-ST960:105:D10GVACXX:2:1101:16973:2166 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCACNGTGTTGGCGTTTTATCTG
++
+IJIIJJIGIHHHCC#4ADDDHHHHHJJJIJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16783:2167 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGGNTGTGCAGACTAAGGAGC
++
+FFFIIIFIIIII@@#4=DDDFFFFFIIIIIII
+ at HWI-ST960:105:D10GVACXX:2:1101:16847:2173 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCGATGTCGGCTCTTCCTATCAT
++
+GIJJJJJJJJJJCCCFDFFFHHHHHJGIGIIIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16809:2177 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACATCCTCATAATCACTTTC
++
+FDHJJEFIGIIJCCCFFFFFHHHHHIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16946:2180 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTCTTTTGTCGGCGTTAGGT
++
+HHHHFFFFEEEECBCFFFFFHHHHHJHJJJJH
+ at HWI-ST960:105:D10GVACXX:2:1101:16831:2183 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTATGTTATGGATTCAAAAAAA
++
+HIJJJJJHHHHH at CCFFFFFHHFHHJIJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16770:2187 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTCAGCCCTTTGTCGCTAAGA
++
+HIJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16858:2188 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAATTTTTAGTGACCCTTTTA
++
+HIJJJIJJJJJJ@@@FFFFFHFFHHJIJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:16876:2193 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATGTTCTCTGTTATTCTC
++
+IIJJJJJJJJJJCBCFFFFFHHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16983:2194 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCTTTGTGGGTTGAGTTGTCT
++
+HIJIJJJJIJHHBCCFFDFFHHHHHJHIJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16842:2205 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTATGAAATCGACCATGACA
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16962:2210 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTCATGCTGTTTTCCAACAGC
++
+IJJEIIJJJIGH at CCFFFFFHHHHHJJIJJJIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16751:2219 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTACTGTTTTCTGTTTTCTT
++
+JJJJJJJJJJJJC at BFFFFFHHHHHHIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16898:2223 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCAACCCCCGAACTATATCCTC
++
+HIJJJJHHHHHFCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16969:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCATTATCTTGTAGAATGTTCA
++
+HGIJJJJJJJJJCCCFFFFFHHHHHJJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:16781:2240 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTTCTCCTCTCGTCCATAAAT
++
+IJJJJJJJJJJHCCCFFFFFHHHHHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17176:2160 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGCNAGATGATGGTCATTATAA
++
+GIJIJJJJJIJJ@@#4ADDFGHHHFGIJJIJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17068:2161 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNCACAAGAAAATCAAATAA
++
+HIJJJJJJJJJJCC#4ADFFHGHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17154:2164 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTNGTGGATGATGAAGAGTT
++
+HII;@HGGHIII@@#44ADDFHHBFGEGGICF
+ at HWI-ST960:105:D10GVACXX:2:1101:17222:2169 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTGGATCCTGTTTTGGATTGT
++
+IIJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17028:2180 1:N:0: bcd:RPI6 seq:CACGCCAATATC
+CACGCCAATATCCTATTTACTATTTGAAAAAGC
++
+IJJIJJJJJJJJCCCFFFFFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17127:2184 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCAATTGGACTGTTTAACGTTT
++
+JGIJJJJJJJJJCCCFFFFFHHHHHJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17143:2189 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCAAATTTCTATATATTGTTTT
++
+JJJGGJIIGJJJ@@;DDFFFHGHHGJJJFHIJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17161:2201 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCTTCTGGACATTAGCCATTAGT
++
+HIJJJJJJJJJJCCCFFFFFHHHGHIJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17133:2206 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCTGCCTTTTCCTTCTTGTCGG
++
+JJJJJJJJJJJJ@@CFFFFFHHHHHJIJIIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17121:2224 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGGCACTTCTGTTCTGATCCT
++
+JJJJJJJJJJJJCCCFFFFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17033:2228 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCACTAGACAAACTCTCAAGA
++
+IJJJJJJJJJJJCCCFFFFFHHHHHJJJJJI
+ at HWI-ST960:105:D10GVACXX:2:1101:17178:2238 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGTTTGTAGTCATAATTTAGT
++
+IJJJJJJJIJJJCBCFFFFFHHHHHJIJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17141:2241 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCGTATGTTTCACTCTGTAACT
++
+JJJJJJIJJJJJCCCFFDFFHHHHHJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17119:2246 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCGAGACCAGATGTGCGATGTTT
++
+IJJJJJJIJJJHCCCFFFFFHHHHHJJJJJIJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17246:2247 1:N:0: bcd:RPI8 seq:CACACTTGAATC
+CACACTTGAATCATTTGGTTAGGTCCTTTGTTC
++
+JJJJJJJJJJJJCCCFFFFFHHHFHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17011:2248 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTTTTGAGGTTTTAAGATGTT
++
+HIJJJJJJJJJJBCCFFFFFFHHHHJJIJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17270:2162 1:N:0: bcd:RPI9 seq:CACGATCAGATC
+CACGATCAGATCCCNCTCTTTCAATGCAAATTT
++
+IJJGJJJJJJJJCC#4ADDFHHHHHJJJJJJJJ
+ at HWI-ST960:105:D10GVACXX:2:1101:17469:2169 1:N:0: bcd:RPI7 seq:CACCAGATCATC
+CACCAGATCATCTGTGTTGGTGAAGGAAGGAAC
++
+GHI at FFG;CHIH@@+ADDDDAFHDFEG@?A?FB
diff --git a/src/libqes/test/data/test.fastq.bz2 b/src/libqes/test/data/test.fastq.bz2
new file mode 100644
index 0000000..e79e99e
Binary files /dev/null and b/src/libqes/test/data/test.fastq.bz2 differ
diff --git a/src/libqes/test/data/test.fastq.gz b/src/libqes/test/data/test.fastq.gz
new file mode 100644
index 0000000..a234381
Binary files /dev/null and b/src/libqes/test/data/test.fastq.gz differ
diff --git a/src/libqes/test/helpers.c b/src/libqes/test/helpers.c
new file mode 100644
index 0000000..d98a733
--- /dev/null
+++ b/src/libqes/test/helpers.c
@@ -0,0 +1,191 @@
+/*
+ * ============================================================================
+ *
+ * Filename: helpers.c
+ *
+ * Description: Helpers for tests
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "helpers.h"
+
+
+/* This is how we name out output files, n_writables is the num of writable
+ files we've made. */
+static int n_writables = 0;
+/* This holds the prefix. It is set (via extern) in test.c's main func. */
+char *data_prefix = NULL;
+
+
+/*=== FUNCTION ============================================================*
+Name: find_data_file
+Paramters: filepath: the file, under ./data, to find
+Description: Finds the full path to ``filepath``
+Returns: A ``char *`` on the heap that contains a valid path to the
+ file ``filepath``, or NULL on error;
+ *===========================================================================*/
+
+char *
+find_data_file(const char * filepath)
+{
+ size_t buflen = 1<<12;
+ size_t len = 0;
+ char buf[buflen];
+
+ /* Bail out if we can't get the data_prefix. */
+ if (data_prefix == NULL) {
+ return NULL;
+ }
+ len = snprintf(buf, buflen, "%s/data/%s", data_prefix, filepath);
+ /* File name is too long, return NULL */
+ if (len >= buflen) {
+ return NULL;
+ }
+ /* Null terminate AFTER making sure len < buflen */
+ buf[len] = '\0';
+ /* Check we can access the file. If so, strdup & return */
+ if (access(buf, F_OK) == 0) {
+ char *ret = malloc(buflen + 1);
+ assert(ret);
+ return strncpy(ret, buf, buflen);
+ }
+ /* If we get to here, something's gone wrong. */
+ return NULL;
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: get_writable_file
+Paramters: void
+Description: Gets a temporary file which can be written to, under the data
+ directory.
+Returns: A ``char *`` on the heap that contains a valid path to a file
+ writable file, or NULL on error;
+ *===========================================================================*/
+
+char *
+get_writable_file(void)
+{
+ size_t buflen = 1<<12;
+ size_t len = 0;
+ char buf[buflen];
+ char *ret = NULL;
+
+ /* Bail out if we can't get the data_prefix. */
+ if (data_prefix == NULL) {
+ return NULL;
+ }
+ len = snprintf(buf, buflen, "%s/data/%05d", data_prefix, n_writables++);
+ /* File name is too long, return NULL */
+ if (len >= buflen) {
+ return NULL;
+ }
+ /* Null terminate AFTER making sure len < buflen */
+ buf[len] = '\0';
+ /* Check we can access the file. If so, strdup & return */
+ ret = malloc(buflen + 1);
+ assert(ret);
+ return strncpy(ret, buf, buflen);
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: clean_writable_file
+Paramters: char *: filename
+Description: Unlink ``file`` and free the memory holding the path.
+Returns: void
+ *===========================================================================*/
+
+void
+clean_writable_file(char *filepath)
+{
+ if (filepath != NULL) {
+ remove(filepath);
+ free(filepath);
+ }
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: crc32_file
+Paramters: char *: filename
+Description: Calculate (using zlib) crc32 checksum.
+Returns: const char *: The crc32 sum, or NULL on error.
+ *===========================================================================*/
+
+char *
+crc32_file(const char *filepath)
+{
+ FILE *fp = NULL;
+ size_t buflen = 1<<10;
+ size_t len = 0;
+ char buffer[buflen];
+ uint32_t crc = 0;
+ char crcbuf[9];
+
+ /* Open file */
+ fp = fopen(filepath, "rb");
+ if (fp == NULL) {
+ return NULL;
+ }
+ while (!feof(fp)) {
+ len = fread(buffer, 1, buflen, fp);
+ crc = crc32_update(crc, buffer, len);
+ }
+ len = snprintf(crcbuf, 9, "%08x", crc);
+ crcbuf[len] = '\0';
+ fclose(fp);
+ return strdup(crcbuf);
+}
+
+int
+filecmp(const char *file1, const char *file2)
+{
+ /* returns: -1 on error, 0 if identical, 1 if not */
+ FILE *fp1 = NULL;
+ FILE *fp2 = NULL;
+ unsigned char *buff1 = NULL;
+ unsigned char *buff2 = NULL;
+ const size_t buff_size = 65535;
+ int retval = 1;
+
+ if (file1 == NULL || file2 == NULL) return -1;
+ fp1 = fopen(file1, "r");
+ fp2 = fopen(file2, "r");
+ buff1 = malloc(buff_size);
+ buff2 = malloc(buff_size);
+ if (fp1 == NULL || fp2 == NULL || buff1 == NULL || buff2 == NULL) {
+ retval = -1;
+ goto exit;
+ }
+
+ while (!feof(fp1) && !feof(fp2)) {
+ size_t bytes_read = 0;
+ size_t res1 = 0;
+ size_t res2 = 0;
+ res1 = fread(buff1, 1, buff_size, fp1);
+ res2 = fread(buff2, 1, buff_size, fp2);
+ if (ferror(fp1) != 0 || ferror(fp2) != 0) {
+ retval = -1;
+ goto exit;
+ }
+ if (res1 != res2) {
+ retval = 1;
+ goto exit;
+ }
+ if (res1 == 0 && res2 == 0) {
+ break;
+ }
+ bytes_read += res1;
+ if (memcmp(buff1, buff2, res1) == 0) retval = 0;
+ }
+exit:
+ if (buff1 != NULL) free(buff1);
+ if (fp1 != NULL) fclose(fp1);
+ if (buff2 != NULL) free(buff2);
+ if (fp2 != NULL) fclose(fp2);
+ return retval;
+}
diff --git a/src/libqes/test/helpers.h b/src/libqes/test/helpers.h
new file mode 100644
index 0000000..111a060
--- /dev/null
+++ b/src/libqes/test/helpers.h
@@ -0,0 +1,40 @@
+/*
+ * ============================================================================
+ *
+ * Filename: helpers.h
+ *
+ * Description: Helpers for tests
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef HELPERS_H
+#define HELPERS_H
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <time.h>
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+#include <qes_libgnu.h>
+
+
+extern char *data_prefix;
+char *find_data_file(const char * filepath);
+char *get_writable_file(void);
+void clean_writable_file(char *filepath);
+char *crc32_file(const char *filepath);
+int filecmp(const char *file1, const char *file2);
+
+#endif /* HELPERS_H */
diff --git a/src/libqes/test/kseq.h b/src/libqes/test/kseq.h
new file mode 100644
index 0000000..a5cec7c
--- /dev/null
+++ b/src/libqes/test/kseq.h
@@ -0,0 +1,235 @@
+/* The MIT License
+
+ Copyright (c) 2008, 2009, 2011 Attractive Chaos <attractor at live.co.uk>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+/* Last Modified: 05MAR2012 */
+
+#ifndef AC_KSEQ_H
+#define AC_KSEQ_H
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define KS_SEP_SPACE 0 // isspace(): \t, \n, \v, \f, \r
+#define KS_SEP_TAB 1 // isspace() && !' '
+#define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows)
+#define KS_SEP_MAX 2
+
+#define __KS_TYPE(type_t) \
+ typedef struct __kstream_t { \
+ unsigned char *buf; \
+ int begin, end, is_eof; \
+ type_t f; \
+ } kstream_t;
+
+#define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end)
+#define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0)
+
+#define __KS_BASIC(type_t, __bufsize) \
+ static inline kstream_t *ks_init(type_t f) \
+ { \
+ kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \
+ ks->f = f; \
+ ks->buf = (unsigned char*)malloc(__bufsize); \
+ return ks; \
+ } \
+ static inline void ks_destroy(kstream_t *ks) \
+ { \
+ if (ks) { \
+ free(ks->buf); \
+ free(ks); \
+ } \
+ }
+
+#define __KS_GETC(__read, __bufsize) \
+ static inline int ks_getc(kstream_t *ks) \
+ { \
+ if (ks->is_eof && ks->begin >= ks->end) return -1; \
+ if (ks->begin >= ks->end) { \
+ ks->begin = 0; \
+ ks->end = __read(ks->f, ks->buf, __bufsize); \
+ if (ks->end < __bufsize) ks->is_eof = 1; \
+ if (ks->end == 0) return -1; \
+ } \
+ return (int)ks->buf[ks->begin++]; \
+ }
+
+#ifndef KSTRING_T
+#define KSTRING_T kstring_t
+typedef struct __kstring_t {
+ size_t l, m;
+ char *s;
+} kstring_t;
+#endif
+
+#ifndef kroundup32
+#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
+#endif
+
+#define __KS_GETUNTIL(__read, __bufsize) \
+ static int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append) \
+ { \
+ if (dret) *dret = 0; \
+ str->l = append? str->l : 0; \
+ if (ks->begin >= ks->end && ks->is_eof) return -1; \
+ for (;;) { \
+ int i; \
+ if (ks->begin >= ks->end) { \
+ if (!ks->is_eof) { \
+ ks->begin = 0; \
+ ks->end = __read(ks->f, ks->buf, __bufsize); \
+ if (ks->end < __bufsize) ks->is_eof = 1; \
+ if (ks->end == 0) break; \
+ } else break; \
+ } \
+ if (delimiter == KS_SEP_LINE) { \
+ for (i = ks->begin; i < ks->end; ++i) \
+ if (ks->buf[i] == '\n') break; \
+ } else if (delimiter > KS_SEP_MAX) { \
+ for (i = ks->begin; i < ks->end; ++i) \
+ if (ks->buf[i] == delimiter) break; \
+ } else if (delimiter == KS_SEP_SPACE) { \
+ for (i = ks->begin; i < ks->end; ++i) \
+ if (isspace(ks->buf[i])) break; \
+ } else if (delimiter == KS_SEP_TAB) { \
+ for (i = ks->begin; i < ks->end; ++i) \
+ if (isspace(ks->buf[i]) && ks->buf[i] != ' ') break; \
+ } else i = 0; /* never come to here! */ \
+ if (str->m - str->l < (size_t)(i - ks->begin + 1)) { \
+ str->m = str->l + (i - ks->begin) + 1; \
+ kroundup32(str->m); \
+ str->s = (char*)realloc(str->s, str->m); \
+ } \
+ memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \
+ str->l = str->l + (i - ks->begin); \
+ ks->begin = i + 1; \
+ if (i < ks->end) { \
+ if (dret) *dret = ks->buf[i]; \
+ break; \
+ } \
+ } \
+ if (str->s == 0) { \
+ str->m = 1; \
+ str->s = (char*)calloc(1, 1); \
+ } else if (delimiter == KS_SEP_LINE && str->l > 1 && str->s[str->l-1] == '\r') --str->l; \
+ str->s[str->l] = '\0'; \
+ return str->l; \
+ } \
+ static inline int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \
+ { return ks_getuntil2(ks, delimiter, str, dret, 0); }
+
+#define KSTREAM_INIT(type_t, __read, __bufsize) \
+ __KS_TYPE(type_t) \
+ __KS_BASIC(type_t, __bufsize) \
+ __KS_GETC(__read, __bufsize) \
+ __KS_GETUNTIL(__read, __bufsize)
+
+#define kseq_rewind(ks) ((ks)->last_char = (ks)->f->is_eof = (ks)->f->begin = (ks)->f->end = 0)
+
+#define __KSEQ_BASIC(SCOPE, type_t) \
+ SCOPE kseq_t *kseq_init(type_t fd) \
+ { \
+ kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \
+ s->f = ks_init(fd); \
+ return s; \
+ } \
+ SCOPE void kseq_destroy(kseq_t *ks) \
+ { \
+ if (!ks) return; \
+ free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \
+ ks_destroy(ks->f); \
+ free(ks); \
+ }
+
+/* Return value:
+ >=0 length of the sequence (normal)
+ -1 end-of-file
+ -2 truncated quality string
+ */
+#define __KSEQ_READ(SCOPE) \
+ SCOPE int kseq_read(kseq_t *seq) \
+ { \
+ int c; \
+ kstream_t *ks = seq->f; \
+ if (seq->last_char == 0) { /* then jump to the next header line */ \
+ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \
+ if (c == -1) return -1; /* end of file */ \
+ seq->last_char = c; \
+ } /* else: the first header char has been read in the previous call */ \
+ seq->comment.l = seq->seq.l = seq->qual.l = 0; /* reset all members */ \
+ if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; /* normal exit: EOF */ \
+ if (c != '\n') ks_getuntil(ks, KS_SEP_LINE, &seq->comment, 0); /* read FASTA/Q comment */ \
+ if (seq->seq.s == 0) { /* we can do this in the loop below, but that is slower */ \
+ seq->seq.m = 256; \
+ seq->seq.s = (char*)malloc(seq->seq.m); \
+ } \
+ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \
+ if (c == '\n') continue; /* skip empty lines */ \
+ seq->seq.s[seq->seq.l++] = c; /* this is safe: we always have enough space for 1 char */ \
+ ks_getuntil2(ks, KS_SEP_LINE, &seq->seq, 0, 1); /* read the rest of the line */ \
+ } \
+ if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \
+ if (seq->seq.l + 1 >= seq->seq.m) { /* seq->seq.s[seq->seq.l] below may be out of boundary */ \
+ seq->seq.m = seq->seq.l + 2; \
+ kroundup32(seq->seq.m); /* rounded to the next closest 2^k */ \
+ seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \
+ } \
+ seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \
+ if (c != '+') return seq->seq.l; /* FASTA */ \
+ if (seq->qual.m < seq->seq.m) { /* allocate memory for qual in case insufficient */ \
+ seq->qual.m = seq->seq.m; \
+ seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \
+ } \
+ while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \
+ if (c == -1) return -2; /* error: no quality string */ \
+ while (ks_getuntil2(ks, KS_SEP_LINE, &seq->qual, 0, 1) >= 0 && seq->qual.l < seq->seq.l); \
+ seq->last_char = 0; /* we have not come to the next header line */ \
+ if (seq->seq.l != seq->qual.l) return -2; /* error: qual string is of a different length */ \
+ return seq->seq.l; \
+ }
+
+#define __KSEQ_TYPE(type_t) \
+ typedef struct { \
+ kstring_t name, comment, seq, qual; \
+ int last_char; \
+ kstream_t *f; \
+ } kseq_t;
+
+#define KSEQ_INIT2(SCOPE, type_t, __read) \
+ KSTREAM_INIT(type_t, __read, 16384) \
+ __KSEQ_TYPE(type_t) \
+ __KSEQ_BASIC(SCOPE, type_t) \
+ __KSEQ_READ(SCOPE)
+
+#define KSEQ_INIT(type_t, __read) KSEQ_INIT2(static, type_t, __read)
+
+#define KSEQ_DECLARE(type_t) \
+ __KS_TYPE(type_t) \
+ __KSEQ_TYPE(type_t) \
+ extern kseq_t *kseq_init(type_t fd); \
+ void kseq_destroy(kseq_t *ks); \
+ int kseq_read(kseq_t *seq);
+
+#endif
diff --git a/src/libqes/test/logdemo.c b/src/libqes/test/logdemo.c
new file mode 100644
index 0000000..82e13ae
--- /dev/null
+++ b/src/libqes/test/logdemo.c
@@ -0,0 +1,34 @@
+/*
+ * ============================================================================
+ *
+ * Filename: logdemo.c
+ * Description: Demontrate libqes logging
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include <qes_log.h>
+
+int
+main (int argc, char *argv[])
+{
+ struct qes_logger *logger = qes_logger_create();
+
+ (void) argc;
+ (void) argv;
+
+ qes_logger_init(logger, "Test Logger", QES_LOG_DEBUG);
+ qes_logger_add_destination_formatted(logger, stdout, QES_LOG_DEBUG,
+ &qes_log_formatter_pretty);
+
+ qes_log_message_debug(logger, "Debug message, nice and quiet\n");
+ qes_log_message_info(logger, "Informative message, clearer\n");
+ qes_log_message_warning(logger, "Warning message, pay attention!\n");
+ qes_log_message_error(logger, "Error message, something's gone wrong\n");
+ qes_log_message_fatal(logger, "Fatal message, I'm leaving now\n");
+
+ qes_logger_destroy(logger);
+ return EXIT_SUCCESS;
+}
diff --git a/src/libqes/test/test.c b/src/libqes/test/test.c
new file mode 100644
index 0000000..4252ef8
--- /dev/null
+++ b/src/libqes/test/test.c
@@ -0,0 +1,64 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test.c
+ *
+ * Description: Tests for libqes
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+
+
+struct testgroup_t libqes_tests[] = {
+ {"qes/util/", qes_util_tests},
+ {"qes/match/", qes_match_tests},
+ {"qes/file/", qes_file_tests},
+ {"qes/seqfile/", qes_seqfile_tests},
+ {"qes/seq/", qes_seq_tests},
+ {"qes/log/", qes_log_tests},
+ {"qes/sequtil/", qes_sequtil_tests},
+ {"testdata/", data_tests},
+ {"testhelpers/", helper_tests},
+ END_OF_GROUPS
+};
+
+
+/*
+ * === FUNCTION =============================================================
+ * Name: main
+ * Description: Run all tests
+ * ============================================================================
+ */
+
+int
+main (int argc, const char *argv[])
+{
+ int res;
+ int our_argc = argc;
+ const char **our_argv = argv;
+
+ data_prefix = NULL;
+ if (argc>1) {
+ data_prefix = strdup(argv[1]);
+ our_argc -= 1;
+ our_argv += 1;
+ }
+ if (data_prefix == NULL) {
+ data_prefix = strdup(".");
+ assert(data_prefix != NULL);
+ }
+ if (access(data_prefix, W_OK | X_OK | R_OK) != 0) {
+ fprintf(stderr, "ERROR: Could not access data prefix dir '%s'\n",
+ data_prefix);
+ fprintf(stderr, "Usage: test_libqes <DATA_DIR> [<test>]\n");
+ free(data_prefix);
+ exit(EXIT_FAILURE);
+ }
+ res = tinytest_main(our_argc, our_argv, libqes_tests);
+ free(data_prefix);
+ return res;
+}
diff --git a/src/libqes/test/test_file.c b/src/libqes/test/test_file.c
new file mode 100644
index 0000000..b2cfc24
--- /dev/null
+++ b/src/libqes/test/test_file.c
@@ -0,0 +1,430 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_file.c
+ *
+ * Description: Test qes_file
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_file.h>
+
+
+static void
+test_qes_file_open (void *ptr)
+{
+ struct qes_file *file = NULL;
+ struct qes_file *badfile = NULL;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Test file opening for reading */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ tt_ptr_op(file, !=, NULL);
+ tt_int_op(file->mode, ==, QES_FILE_MODE_READ);
+ qes_file_close(file);
+ free(fname);
+ /* test zipped file opening for reading */
+ fname = find_data_file("loremipsum.txt.gz");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ tt_ptr_op(file, !=, NULL);
+ tt_int_op(file->mode, ==, QES_FILE_MODE_READ);
+ qes_file_close(file);
+ free(fname);
+ /* read with non-existant file */
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ tt_ptr_op(file, ==, NULL);
+ clean_writable_file(fname);
+ fname = NULL;
+ /* writing with gziped file */
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "w");
+ tt_ptr_op(file, !=, NULL);
+ tt_int_op(file->mode, ==, QES_FILE_MODE_WRITE);
+ clean_writable_file(fname);
+ fname = NULL;
+ /* With non-existant file path */
+ badfile = qes_file_open("non/existant.file", "w");
+ tt_ptr_op(badfile, ==, NULL);
+
+end:
+ qes_file_close(file);
+ qes_file_close(badfile);
+ if (fname != NULL) free(fname);
+}
+
+static void
+test_qes_file_close (void *ptr)
+{
+ struct qes_file *file = NULL;
+ struct qes_file *nullfile = NULL;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ tt_assert(file);
+ qes_file_close(file);
+ tt_ptr_op(file, ==, NULL);
+ /* check with null poitner, ensure no problems are caused. */
+ qes_file_close(nullfile);
+ tt_ptr_op(nullfile, ==, NULL);
+end:
+ qes_file_close(file);
+ free(fname);
+}
+
+
+static void
+test_qes_file_rewind (void *ptr)
+{
+ struct qes_file *file = NULL;
+ size_t bufsize = 1<<10;
+ char buffer[bufsize];
+ ssize_t res = 0;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ tt_assert(file);
+ while (res != EOF) {
+ res = qes_file_readline(file, buffer, bufsize);
+ }
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ tt_int_op(QES_ZTELL(file->fp), ==, loremipsum_fsize);
+ tt_assert(file->eof);
+ tt_assert(file->feof);
+ qes_file_rewind(file);
+ tt_int_op(file->filepos, ==, 0);
+ tt_assert(!file->eof);
+ tt_assert(!file->feof);
+ tt_int_op(QES_ZTELL(file->fp), ==, 0);
+end:
+ qes_file_close(file);
+ free(fname);
+}
+
+static void
+test_qes_file_readline (void *ptr)
+{
+ struct qes_file *file = NULL;
+ size_t bufsize = 1<<10;
+ char buffer[bufsize];
+ ssize_t res_len = 0;
+ off_t orig_filepos = 0;
+ size_t iii;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ /* Check each line is of the right length, that the length is returned,
+ * that the string is as expected, and that file->filepos is updated.
+ */
+ for (iii = 0; iii < n_loremipsum_lines; iii++) {
+ orig_filepos = file->filepos;
+ res_len = qes_file_readline(file, buffer, bufsize);
+ tt_int_op(res_len, ==, strlen(buffer));
+ tt_int_op(res_len, ==, loremipsum_line_lens[iii]);
+ tt_str_op(buffer, ==, loremipsum_lines[iii]);
+ tt_int_op(file->filepos - orig_filepos, ==, loremipsum_line_lens[iii]);
+ }
+ /* Check that a file at EOF returns EOF. */
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ tt_int_op(qes_file_readline(file, buffer, bufsize), ==, EOF);
+ tt_assert(file->eof)
+ /* Test with bad parameters */
+ tt_int_op(qes_file_readline(NULL, buffer, bufsize), ==, -2);
+ tt_int_op(qes_file_readline(file, NULL, bufsize), ==, -2);
+ tt_int_op(qes_file_readline(file, buffer, 0), ==, -2);
+
+end:
+ qes_file_close(file);
+ free(fname);
+}
+
+static void
+test_qes_file_getuntil (void *ptr)
+{
+ struct qes_file *file = NULL;
+ const size_t bufsize = 1<<10;
+ char buffer[bufsize];
+ ssize_t res_len = 0;
+ size_t expt_len = 0;
+ off_t orig_filepos = 0;
+ off_t our_filepos = 0;
+ size_t iii;
+ const size_t n_delims = 5;
+ const int delims[] = {' ', ',', '.', '\n', '\n'};
+ const char *delim_words[] = {
+ "Lorem ",
+ "ipsum dolor sit amet,",
+ " consectetur adipiscing elit.",
+ " Donec ornare tortor et\n",
+ "rhoncus iaculis. Sed suscipit, arcu nec elementum vestibulum, tortor tortor\n",
+ };
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ /* Check each token is of the right length, that the length is returned,
+ * that the string is as expected, and that file->filepos is updated.
+ */
+ for (iii = 0; iii < n_delims; iii++) {
+ orig_filepos = file->filepos;
+ res_len = qes_file_getuntil(file, delims[iii], buffer, bufsize);
+ our_filepos += res_len;
+ expt_len = strnlen(delim_words[iii], bufsize);
+ tt_int_op(res_len, ==, strnlen(buffer, bufsize));
+ tt_int_op(res_len, ==, expt_len);
+ tt_str_op(buffer, ==, delim_words[iii]);
+ tt_int_op(file->filepos - orig_filepos, ==, expt_len);
+ tt_int_op(file->filepos, ==, our_filepos);
+ }
+ /* Check we can give EOF as the char and make it give us the remainder of
+ the file */
+ orig_filepos = file->filepos;
+ res_len = qes_file_getuntil(file, EOF, buffer, bufsize);
+ expt_len = loremipsum_fsize - our_filepos;
+ our_filepos += res_len;
+ tt_int_op(res_len, ==, strnlen(buffer, bufsize));
+ tt_int_op(res_len, ==, expt_len);
+ tt_int_op(file->filepos - orig_filepos, ==, expt_len);
+ tt_int_op(file->filepos, ==, our_filepos);
+ tt_assert(file->eof)
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ /* Check that a file at EOF returns EOF. */
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ tt_int_op(qes_file_getuntil(file, '\n', buffer, bufsize), ==, EOF);
+ tt_assert(file->eof)
+ /* Test with bad parameters */
+ QES_ZREWIND(file->fp);
+ file->eof = 0;
+ file->filepos = 0;
+ tt_int_op(qes_file_getuntil(NULL, '\n', buffer, bufsize), ==, -2);
+ tt_int_op(qes_file_getuntil(file, 256, buffer, bufsize), ==, -2);
+ tt_int_op(qes_file_getuntil(file, '\n', NULL, bufsize), ==, -2);
+ tt_int_op(qes_file_getuntil(file, '\n', buffer, 0), ==, -2);
+end:
+ qes_file_close(file);
+ if (fname != NULL) free(fname);
+}
+
+static void
+test_qes_file_peek (void *ptr)
+{
+ int res = 0;
+ struct qes_file *file = NULL;
+ off_t orig_filepos = 0;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file and save pos */
+ fname = find_data_file("loremipsum.txt");
+ tt_assert(fname != NULL);
+ file = qes_file_open(fname, "r");
+ orig_filepos = file->filepos;
+ /* Peek a char */
+ res = qes_file_peek(file);
+ /* Check it's the right char */
+ tt_int_op(res, ==, loremipsum_lines[0][0]);
+ /* And that the filepos hasn't changed */
+ tt_int_op(file->filepos , ==, orig_filepos);
+ /* And that the same char is returned again */
+ res = qes_file_peek(file);
+ tt_int_op(res, ==, loremipsum_lines[0][0]);
+ /* And that it returns an error on being given a null pointer */
+ tt_int_op(qes_file_peek(NULL), ==, -2);
+end:
+ qes_file_close(file);
+ if (fname != NULL) free(fname);
+}
+
+static void
+test_qes_file_guess_mode (void *ptr)
+{
+ const char *modes[] = {
+ "r", "rb", "rb8", "rT", "rbT",
+ "w", "wb", "wb8", "wT", "wbT",
+ "a", "ab", "ab8", "aT", "abT",
+ "+", "+b", "+b8", "+T", "+bT",
+ };
+ const int mode_results[] = {
+ QES_FILE_MODE_READ, QES_FILE_MODE_READ, QES_FILE_MODE_READ,
+ QES_FILE_MODE_READ, QES_FILE_MODE_READ, QES_FILE_MODE_WRITE,
+ QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE,
+ QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE,
+ QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE, QES_FILE_MODE_WRITE,
+ QES_FILE_MODE_UNKNOWN, QES_FILE_MODE_UNKNOWN, QES_FILE_MODE_UNKNOWN,
+ QES_FILE_MODE_UNKNOWN, QES_FILE_MODE_UNKNOWN,
+ };
+ const size_t num_modes = 20;
+ size_t iii;
+ (void) ptr;
+ for (iii = 0; iii < num_modes; iii++) {
+ tt_int_op(qes_file_guess_mode(modes[iii]), ==, mode_results[iii]);
+ }
+end:
+ ;
+}
+
+static void
+test_qes_file_readline_realloc (void *ptr)
+{
+ char *buf = NULL;
+ char *smallbuf = NULL;
+ const size_t smallbuf_len = 4;
+ const size_t buf_len = 1<<10; /* 1024b */
+ struct qes_file *file = NULL;
+ ssize_t ret = 0;
+ off_t fpos = 0;
+ size_t line_num;
+ char *nulcp = NULL;
+ size_t tmpsz = buf_len;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Open file and save pos */
+ fname = find_data_file("loremipsum.txt");
+ /* This should always work, so long as you run it from the right dir */
+ file = qes_file_open(fname, "r");
+ buf = calloc(buf_len, sizeof(*buf));
+ smallbuf = calloc(smallbuf_len, sizeof(*smallbuf));
+ tt_assert(file && buf && smallbuf);
+ /* Check each line is of the right length, that the length is returned,
+ * that the string is as expected, and that file->filepos is updated.
+ */
+ for (line_num = 0; line_num < n_loremipsum_lines; line_num++) {
+ ret = qes_file_readline_realloc(file, &buf, &tmpsz);
+ fpos += ret;
+ tt_int_op(fpos, ==, file->filepos);
+ tt_str_op(buf, ==, loremipsum_lines[line_num]);
+ tt_int_op(strlen(buf), ==, loremipsum_line_lens[line_num]);
+ tt_int_op(ret, ==, loremipsum_line_lens[line_num]);
+ tt_int_op(buf[ret], ==, '\0');
+ tt_int_op(tmpsz, ==, buf_len);
+ tt_int_op(tmpsz, >=, qes_roundupz(loremipsum_line_lens[line_num]));
+ }
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ ret = qes_file_readline_realloc(file, &buf, &tmpsz);
+ tt_assert(file->eof);
+ tt_int_op(ret, ==, EOF);
+ qes_file_close(file);
+ /*
+ * Test w/ small buffer
+ */
+ /* Do the same checks, but with a buffer that needs resizing */
+ file = qes_file_open(fname, "r");
+ tmpsz = smallbuf_len;
+ fpos = 0;
+ for (line_num = 0; line_num < n_loremipsum_lines; line_num++) {
+ ret = qes_file_readline_realloc(file, &smallbuf, &tmpsz);
+ fpos += ret;
+ tt_int_op(fpos, ==, file->filepos);
+ tt_str_op(smallbuf, ==, loremipsum_lines[line_num]);
+ tt_int_op(strlen(smallbuf), ==, loremipsum_line_lens[line_num]);
+ tt_int_op(ret, ==, loremipsum_line_lens[line_num]);
+ tt_int_op(tmpsz, !=, smallbuf_len);
+ tt_int_op(tmpsz, >=, qes_roundupz(loremipsum_line_lens[line_num]));
+ tt_int_op(smallbuf[ret], ==, '\0');
+ }
+ tt_int_op(file->filepos, ==, loremipsum_fsize);
+ /* Test with EOF file */
+ tmpsz = buf_len;
+ ret = qes_file_readline_realloc(file, &buf, &tmpsz);
+ tt_int_op(ret, ==, EOF);
+ tt_str_op(buf, ==, "");
+ tt_int_op(strlen(buf), ==, 0);
+ tt_int_op(tmpsz, ==, buf_len);
+ tt_assert(file->eof)
+ qes_file_close(file);
+ /*
+ * Test bad things
+ */
+ /* Null buf. Should alloc a buffer and fill it */
+ file = qes_file_open(fname, "r");
+ line_num = 0;
+ ret = qes_file_readline_realloc(file, &nulcp, &tmpsz);
+ tt_int_op(ret, ==, loremipsum_line_lens[line_num]);
+ tt_str_op(nulcp, ==, loremipsum_lines[line_num]);
+ tt_int_op(strlen(nulcp), ==, loremipsum_line_lens[line_num]);
+ tt_int_op(tmpsz, ==, __INIT_LINE_LEN);
+ /* Null file */
+ ret = qes_file_readline_realloc(NULL, &buf, &tmpsz);
+ tt_int_op(ret, ==, -2);
+ /* This shouldn't change and is set in the prev. test */
+ tt_int_op(tmpsz, ==, __INIT_LINE_LEN);
+ /* Both buf & file null */
+ ret = qes_file_readline_realloc(NULL, &nulcp, &tmpsz);
+ tt_int_op(ret, ==, -2);
+ tt_int_op(tmpsz, ==, __INIT_LINE_LEN);
+end:
+ if (buf != NULL) free(buf);
+ if (smallbuf != NULL) free(smallbuf);
+ if (nulcp != NULL) free(nulcp);
+ if (file != NULL) qes_file_close(file);
+ free(fname);
+}
+
+static void
+test_qes_file_ok (void *ptr)
+{
+ struct qes_file *file;
+ char *writeable = NULL;
+ char *readable = NULL;
+
+ (void) ptr;
+ readable = find_data_file("loremipsum.txt");
+ writeable = get_writable_file();
+ /* Should result in an OK file */
+ file = qes_file_open(readable, "r");
+ tt_assert(qes_file_ok(file));
+ tt_assert(qes_file_readable(file));
+ qes_file_close(file);
+ file = qes_file_open("nosuchfile", "r");
+ tt_assert(!qes_file_ok(file));
+ tt_assert(!qes_file_readable(file));
+ qes_file_close(file);
+ file = qes_file_open(writeable, "w");
+ tt_assert(qes_file_ok(file));
+ tt_assert(!qes_file_readable(file));
+ qes_file_close(file);
+end:
+ if (file != NULL) qes_file_close(file);
+ clean_writable_file(writeable);
+ free(readable);
+
+}
+
+struct testcase_t qes_file_tests[] = {
+ { "qes_file_open", test_qes_file_open, 0, NULL, NULL},
+ { "qes_file_peek", test_qes_file_peek, 0, NULL, NULL},
+ { "qes_file_readline", test_qes_file_readline, 0, NULL, NULL},
+ { "qes_file_readline_realloc", test_qes_file_readline_realloc, 0, NULL, NULL},
+ { "qes_file_guess_mode", test_qes_file_guess_mode, 0, NULL, NULL},
+ { "qes_file_close", test_qes_file_close, 0, NULL, NULL},
+ { "qes_file_rewind", test_qes_file_rewind, 0, NULL, NULL},
+ { "qes_file_getuntil", test_qes_file_getuntil, 0, NULL, NULL},
+ { "qes_file_ok", test_qes_file_ok, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_helpers.c b/src/libqes/test/test_helpers.c
new file mode 100644
index 0000000..25d477d
--- /dev/null
+++ b/src/libqes/test/test_helpers.c
@@ -0,0 +1,54 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_helpers.c
+ *
+ * Description: Tests of test/helpers.c
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+
+
+static void
+test_crc32_file(void *data)
+{
+ char *crc = NULL;
+ char *fname = NULL;
+
+ (void) data;
+ fname = find_data_file("loremipsum.txt");
+ crc = crc32_file(fname);
+ tt_str_op(crc, ==, "9f20f7ec");
+end:
+ free(fname);
+ free(crc);
+}
+
+static void
+test_filecmp(void *data)
+{
+ char *fname1 = NULL;
+ char *fname2 = NULL;
+
+ (void) data;
+ fname1 = find_data_file("loremipsum.txt");
+ fname2 = find_data_file("loremipsum.txt.gz");
+ tt_int_op(filecmp(fname1, fname1), ==, 0);
+ tt_int_op(filecmp(fname1, fname2), ==, 1);
+ tt_int_op(filecmp(NULL, fname2), ==, -1);
+ tt_int_op(filecmp("/does/not/exist/", fname2), ==, -1);
+
+end:
+ free(fname1);
+ free(fname2);
+}
+
+struct testcase_t helper_tests[] = {
+ { "crc32_file", test_crc32_file, 0, NULL, NULL},
+ { "filecmp", test_filecmp, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_log.c b/src/libqes/test/test_log.c
new file mode 100644
index 0000000..726218d
--- /dev/null
+++ b/src/libqes/test/test_log.c
@@ -0,0 +1,173 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_log.c
+ *
+ * Description: Test logging
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_util.h>
+#include <qes_log.h>
+
+
+static void
+test_qes_logger_setup(void *ptr)
+{
+ int res = 0;
+ struct qes_logger *logger = NULL;
+
+ (void) ptr;
+ /* Test that when created, the logger has logical initial values */
+ logger = qes_logger_create();
+ tt_ptr_op(logger, !=, NULL);
+ tt_ptr_op(logger->destinations, ==, NULL);
+ tt_ptr_op(logger->name, ==, NULL);
+ tt_int_op(logger->n_destinations, ==, 0);
+ tt_int_op(logger->level, ==, QES_LOG_DEBUG);
+ tt_int_op(logger->lock, ==, 0);
+
+ /* Add a destination, check it is there */
+ res = qes_logger_add_destination(logger, stderr, QES_LOG_ERROR);
+ tt_int_op(res, ==, 0);
+ tt_ptr_op(logger->destinations, !=, NULL);
+ tt_ptr_op(logger->destinations[0].stream, ==, stderr);
+ tt_int_op(logger->destinations[0].level, ==, QES_LOG_ERROR);
+ tt_int_op(logger->n_destinations, ==, 1);
+ qes_logger_destroy(logger);
+ tt_ptr_op(logger, ==, NULL);
+
+end:
+ if (logger != NULL) {
+ if (logger->destinations != NULL) free(logger->destinations);
+ if (logger->name != NULL) free(logger->name);
+ free(logger);
+ }
+}
+
+
+static void
+test_qes_logger_init(void *ptr)
+{
+ int res = 0;
+ struct qes_logger *logger = NULL;
+
+ (void) ptr;
+ logger = qes_logger_create();
+ tt_ptr_op(logger, !=, NULL);
+
+ /* Test the init function sets values correctly */
+ res = qes_logger_init(logger, "test logger", QES_LOG_INFO);
+ tt_int_op(res, ==, 0);
+ tt_ptr_op(logger->name, !=, NULL);
+ tt_int_op(logger->level, ==, QES_LOG_INFO);
+ tt_int_op(logger->lock, ==, 0);
+
+ /* test that we error out if we give init NULL */
+ res = qes_logger_init(NULL, "test logger", QES_LOG_INFO);
+ tt_int_op(res, ==, 1);
+
+ /* Test that we silently set logger->name to NULL if we pass NULL */
+ res = qes_logger_init(logger, NULL, QES_LOG_INFO);
+ tt_int_op(res, ==, 0);
+ tt_ptr_op(logger->name, ==, NULL);
+
+end:
+ if (logger != NULL) {
+ if (logger->destinations != NULL) free(logger->destinations);
+ if (logger->name != NULL) free(logger->name);
+ free(logger);
+ }
+}
+
+static void
+test_qes_logger_logging(void *ptr)
+{
+ int res = 0;
+ struct qes_logger *logger = NULL;
+ char *log_fname = NULL;
+ char *truth_fname = NULL;
+ FILE *log_file = NULL;
+
+ (void) ptr;
+ /* Set up a logger, with an acutal file as output */
+ logger = qes_logger_create();
+ tt_ptr_op(logger, !=, NULL);
+ truth_fname = find_data_file("log_test.txt");
+ tt_ptr_op(truth_fname, !=, NULL);
+ log_fname = get_writable_file();
+ tt_ptr_op(log_fname, !=, NULL);
+ log_file = fopen(log_fname, "w");
+ tt_ptr_op(log_file, !=, NULL);
+ res = qes_logger_add_destination(logger, log_file, QES_LOG_INFO);
+ tt_int_op(res, ==, 0);
+
+ /* Test printing to the file using the message functions */
+ qes_log_message_debug(logger, "Hello World\n"); /* wont' print */
+ qes_log_message_info(logger, "Hello World\n"); /* should print */
+
+ /* Test printing to the file with the format functions */
+ qes_log_format_debug(logger, "%s\n", "Hello World");
+ qes_log_format_info(logger, "%s\n", "Hello World");
+
+ /* Test the output file was created correctly */
+ tt_int_op(filecmp(log_fname, truth_fname), ==, 0);
+
+end:
+ if (log_file != NULL) fclose(log_file);
+ if (truth_fname != NULL) free(truth_fname);
+ if (log_fname != NULL) free(log_fname);
+ qes_logger_destroy(logger);
+}
+
+static void
+test_qes_log_entry(void *ptr)
+{
+ int res = 0;
+ struct qes_log_entry *entry = NULL;
+
+ (void) ptr;
+ /* Test that create gives us a valid entry with sane defaults */
+ entry = qes_log_entry_create();
+ tt_ptr_op(entry, !=, NULL);
+ tt_ptr_op(entry->message, ==, NULL);
+ tt_int_op(entry->level, ==, QES_LOG_DEBUG);
+
+ /* Check that init fills the entry appropriately */
+ res = qes_log_entry_init(entry, QES_LOG_ERROR, "Test");
+ tt_int_op(res, ==, 0);
+ tt_ptr_op(entry, !=, NULL);
+ tt_str_op(entry->message, ==, "Test");
+ tt_int_op(entry->level, ==, QES_LOG_ERROR);
+
+ /* test that clear clears an entry, without freeing the entry itself */
+ qes_log_entry_clear(entry);
+ tt_ptr_op(entry, !=, NULL);
+ tt_ptr_op(entry->message, ==, NULL);
+ tt_int_op(entry->level, ==, QES_LOG_DEBUG);
+
+ /* test formatting an entry */
+ res = qes_log_entry_format(entry, QES_LOG_ERROR, "%s", "Test");
+ tt_int_op(res, ==, 0);
+ tt_ptr_op(entry, !=, NULL);
+ tt_str_op(entry->message, ==, "Test");
+ tt_int_op(entry->level, ==, QES_LOG_ERROR);
+
+ qes_log_entry_destroy(entry);
+ tt_ptr_op(entry, ==, NULL);
+
+end:
+ qes_log_entry_destroy(entry);
+}
+
+struct testcase_t qes_log_tests[] = {
+ { "qes_logger_setup", test_qes_logger_setup, 0, NULL, NULL},
+ { "qes_logger_init", test_qes_logger_init, 0, NULL, NULL},
+ { "qes_logger_logging", test_qes_logger_logging, 0, NULL, NULL},
+ { "qes_log_entry", test_qes_log_entry, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_match.c b/src/libqes/test/test_match.c
new file mode 100644
index 0000000..b287368
--- /dev/null
+++ b/src/libqes/test/test_match.c
@@ -0,0 +1,89 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_match.c
+ *
+ * Description: Test qes_match functions
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_match.h>
+#include <limits.h>
+
+
+static void
+test_qes_hamming (void *p)
+{
+ (void) (p);
+ /* Simple stuff */
+ tt_int_op(qes_match_hamming("ACTTG", "ACTTG", 5), ==, 0);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTGG", 5), ==, 1);
+ /* Different lengths */
+ tt_int_op(qes_match_hamming("ACTTGA", "ACTTG", 5), ==, 0);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTTGA", 5), ==, 0);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTGGA", 5), ==, 1);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTGGA", 6), ==, 2);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTTGA", 6), ==, 1);
+ /* Make it guess lengths */
+ tt_int_op(qes_match_hamming("ACTTG", "ACTTG", 0), ==, 0);
+ tt_int_op(qes_match_hamming("ACATG", "ACTTG", 0), ==, 1);
+ tt_int_op(qes_match_hamming("ACTTG", "ACTTGT", 0), ==, 0);
+ tt_int_op(qes_match_hamming("ACATG", "ACTTGT", 0), ==, 1);
+ tt_int_op(qes_match_hamming("ACTTGT", "ACTTG", 0), ==, 0);
+ /* Give it hell */
+ tt_int_op(qes_match_hamming("ACTTG", NULL, 0), ==, -1);
+ tt_int_op(qes_match_hamming(NULL, "ACTTG", 0), ==, -1);
+ tt_int_op(qes_match_hamming(NULL, NULL, 0), ==, -1);
+end:
+ ;
+}
+
+
+static void
+test_qes_hamming_max (void *p)
+{
+
+ (void) (p);
+ /* Same tests as per hamming, max is INT_MAX */
+ /* Simple stuff */
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTG", 5, INT_MAX), ==, 0);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGG", 5, INT_MAX), ==, 1);
+ /* Different lengths */
+ tt_int_op(qes_match_hamming_max("ACTTGA", "ACTTG", 5, INT_MAX), ==, 0);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTGA", 5, INT_MAX), ==, 0);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGGA", 5, INT_MAX), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGGA", 6, INT_MAX), ==, 2);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTGA", 6, INT_MAX), ==, 1);
+ /* Make it guess lengths */
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTG", 0, INT_MAX), ==, 0);
+ tt_int_op(qes_match_hamming_max("ACATG", "ACTTG", 0, INT_MAX), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTGT", 0, INT_MAX), ==, 0);
+ tt_int_op(qes_match_hamming_max("ACATG", "ACTTGT", 0, INT_MAX), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTGT", "ACTTG", 0, INT_MAX), ==, 0);
+ /* Test it bails out when over ``max`` */
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGG", 5, 1), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGG", 5, 0), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGA", 5, 0), ==, 1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGA", 5, 1), ==, 2);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTGA", 5, 2), ==, 2);
+ /* Give it hell */
+ tt_int_op(qes_match_hamming_max("ACTTG", NULL, 0, INT_MAX), ==, -1);
+ tt_int_op(qes_match_hamming_max(NULL, "ACTTG", 0, INT_MAX), ==, -1);
+ tt_int_op(qes_match_hamming_max(NULL, NULL, 0, INT_MAX), ==, -1);
+ tt_int_op(qes_match_hamming_max("ACTTG", "ACTTG", 0, -1), ==, -1);
+ tt_int_op(qes_match_hamming_max("ACTTG", NULL, 0, -1), ==, -1);
+ tt_int_op(qes_match_hamming_max(NULL, "ACTTG", 0, -1), ==, -1);
+ tt_int_op(qes_match_hamming_max(NULL, NULL, 0, -1), ==, -1);
+end:
+ ;
+}
+
+struct testcase_t qes_match_tests[] = {
+ { "qes_match_hamming", test_qes_hamming, 0, NULL, NULL},
+ { "qes_match_hamming_max", test_qes_hamming_max, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_seq.c b/src/libqes/test/test_seq.c
new file mode 100644
index 0000000..5b67b6a
--- /dev/null
+++ b/src/libqes/test/test_seq.c
@@ -0,0 +1,422 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_seq.c
+ *
+ * Description: Test qes_seq.c
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_seq.h>
+
+
+static void
+test_qes_seq_create (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ (void) ptr;
+ tt_ptr_op(seq, ==, NULL);
+ seq = qes_seq_create();
+ tt_ptr_op(seq, !=, NULL);
+ tt_ptr_op(seq->name.str, !=, NULL);
+ tt_int_op(seq->name.capacity, >, 0);
+ tt_int_op(seq->name.len, ==, 0);
+ tt_ptr_op(seq->comment.str, !=, NULL);
+ tt_int_op(seq->comment.capacity, >, 0);
+ tt_int_op(seq->comment.len, ==, 0);
+ tt_ptr_op(seq->seq.str, !=, NULL);
+ tt_int_op(seq->seq.capacity, >, 0);
+ tt_int_op(seq->seq.len, ==, 0);
+ tt_ptr_op(seq->qual.str, !=, NULL);
+ tt_int_op(seq->qual.capacity, >, 0);
+ tt_int_op(seq->qual.len, ==, 0);
+ tt_assert(qes_str_ok(&seq->name));
+ tt_assert(qes_str_ok(&seq->comment));
+ tt_assert(qes_str_ok(&seq->seq));
+ tt_assert(qes_str_ok(&seq->qual));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_create_no_qual (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ (void) ptr;
+ tt_ptr_op(seq, ==, NULL);
+ seq = qes_seq_create_no_qual();
+ tt_ptr_op(seq, !=, NULL);
+ tt_ptr_op(seq->name.str, !=, NULL);
+ tt_int_op(seq->name.capacity, >, 0);
+ tt_int_op(seq->name.len, ==, 0);
+ tt_ptr_op(seq->comment.str, !=, NULL);
+ tt_int_op(seq->comment.capacity, >, 0);
+ tt_int_op(seq->comment.len, ==, 0);
+ tt_ptr_op(seq->seq.str, !=, NULL);
+ tt_int_op(seq->seq.capacity, >, 0);
+ tt_int_op(seq->seq.len, ==, 0);
+ tt_ptr_op(seq->qual.str, ==, NULL);
+ tt_int_op(seq->qual.capacity, ==, 0);
+ tt_int_op(seq->qual.len, ==, 0);
+ tt_assert(qes_str_ok(&seq->name));
+ tt_assert(qes_str_ok(&seq->comment));
+ tt_assert(qes_str_ok(&seq->seq));
+ tt_assert(!qes_str_ok(&seq->qual));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_create_no_qual_or_comment (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ (void) ptr;
+ tt_ptr_op(seq, ==, NULL);
+ seq = qes_seq_create_no_qual_or_comment();
+ tt_ptr_op(seq, !=, NULL);
+ tt_ptr_op(seq->name.str, !=, NULL);
+ tt_int_op(seq->name.capacity, >, 0);
+ tt_int_op(seq->name.len, ==, 0);
+ tt_ptr_op(seq->comment.str, ==, NULL);
+ tt_int_op(seq->comment.capacity, ==, 0);
+ tt_int_op(seq->comment.len, ==, 0);
+ tt_ptr_op(seq->seq.str, !=, NULL);
+ tt_int_op(seq->seq.capacity, >, 0);
+ tt_int_op(seq->seq.len, ==, 0);
+ tt_ptr_op(seq->qual.str, ==, NULL);
+ tt_int_op(seq->qual.capacity, ==, 0);
+ tt_int_op(seq->qual.len, ==, 0);
+ tt_assert(qes_str_ok(&seq->name));
+ tt_assert(!qes_str_ok(&seq->comment));
+ tt_assert(qes_str_ok(&seq->seq));
+ tt_assert(!qes_str_ok(&seq->qual));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_ok (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ (void) ptr;
+ /* Test null seq */
+ tt_assert(!qes_seq_ok(seq));
+ /* Make valid seq */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok(seq));
+ /* invalidate name, should fail */
+ qes_str_destroy_cp(&seq->name);
+ tt_assert(!qes_seq_ok(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok(seq));
+ /* invalidate comment, should fail */
+ qes_str_destroy_cp(&seq->comment);
+ tt_assert(!qes_seq_ok(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok(seq));
+ /* invalidate seq, should fail */
+ qes_str_destroy_cp(&seq->seq);
+ tt_assert(!qes_seq_ok(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok(seq));
+ /* invalidate qual, should fail */
+ qes_str_destroy_cp(&seq->qual);
+ tt_assert(!qes_seq_ok(seq));
+ qes_seq_destroy(seq);
+ /* Destroy seq, invalidating it */
+ qes_seq_destroy(seq);
+ tt_assert(!qes_seq_ok(seq));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_ok_no_comment (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+
+ (void) ptr;
+ /* Test null seq */
+ tt_assert(!qes_seq_ok_no_comment(seq));
+ /* Make valid seq */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment(seq));
+ /* invalidate name, should fail */
+ qes_str_destroy_cp(&seq->name);
+ tt_assert(!qes_seq_ok_no_comment(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment(seq));
+ /* invalidate comment, should still pass */
+ qes_str_destroy_cp(&seq->comment);
+ tt_assert(qes_seq_ok_no_comment(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment(seq));
+ /* invalidate seq, should fail */
+ qes_str_destroy_cp(&seq->seq);
+ tt_assert(!qes_seq_ok_no_comment(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment(seq));
+ /* invalidate qual, should fail */
+ qes_str_destroy_cp(&seq->qual);
+ tt_assert(!qes_seq_ok_no_comment(seq));
+ qes_seq_destroy(seq);
+ /* Destroy seq, invalidating it */
+ qes_seq_destroy(seq);
+ tt_assert(!qes_seq_ok_no_comment(seq));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_ok_no_qual (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ (void) ptr;
+ /* Test null seq */
+ tt_assert(!qes_seq_ok_no_qual(seq));
+ /* Make valid seq */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_qual(seq));
+ /* invalidate name, should fail */
+ qes_str_destroy_cp(&seq->name);
+ tt_assert(!qes_seq_ok_no_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_qual(seq));
+ /* invalidate comment, should fail */
+ qes_str_destroy_cp(&seq->comment);
+ tt_assert(!qes_seq_ok_no_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_qual(seq));
+ /* invalidate seq, should fail */
+ qes_str_destroy_cp(&seq->seq);
+ tt_assert(!qes_seq_ok_no_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_qual(seq));
+ /* invalidate qual, should PASS */
+ qes_str_destroy_cp(&seq->qual);
+ tt_assert(qes_seq_ok_no_qual(seq));
+ qes_seq_destroy(seq);
+ /* Destroy seq, invalidating it */
+ qes_seq_destroy(seq);
+ tt_assert(!qes_seq_ok_no_qual(seq));
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_ok_no_comment_or_qual (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+
+ (void) ptr;
+ /* Test null seq */
+ tt_assert(!qes_seq_ok_no_comment_or_qual(seq));
+ /* Make valid seq */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ /* invalidate name, should fail */
+ qes_str_destroy_cp(&seq->name);
+ tt_assert(!qes_seq_ok_no_comment_or_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ /* invalidate comment, should still pass */
+ qes_str_destroy_cp(&seq->comment);
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ /* invalidate seq, should fail */
+ qes_str_destroy_cp(&seq->seq);
+ tt_assert(!qes_seq_ok_no_comment_or_qual(seq));
+ qes_seq_destroy(seq);
+ /* remake */
+ seq = qes_seq_create();
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ /* invalidate qual, should fail */
+ qes_str_destroy_cp(&seq->qual);
+ tt_assert(qes_seq_ok_no_comment_or_qual(seq));
+ qes_seq_destroy(seq);
+ /* Destroy seq, invalidating it */
+ qes_seq_destroy(seq);
+ tt_assert(!qes_seq_ok_no_comment_or_qual(seq));
+end:
+ qes_seq_destroy(seq);
+}
+
+
+static void
+test_qes_seq_destroy (void *ptr)
+{
+ struct qes_seq *seq = NULL;
+
+ (void) ptr;
+ tt_ptr_op(seq, ==, NULL);
+ seq = qes_seq_create();
+ tt_ptr_op(seq, !=, NULL);
+ qes_seq_destroy(seq);
+ tt_ptr_op(seq, ==, NULL);
+ seq = NULL; /* Best be sure */
+ qes_seq_destroy(seq);
+end:
+ qes_seq_destroy(seq);
+}
+
+static void
+test_qes_seq_copy(void *ptr)
+{
+ struct qes_seq *seq = NULL;
+ struct qes_seq *copy = NULL;
+ int res = 1;
+
+ (void) ptr;
+ seq = qes_seq_create();
+ copy = qes_seq_create();
+ res = qes_seq_fill(seq, "TEST", "Comment 1", "AGCT", "IIII");
+ tt_int_op(res, ==, 0);
+ tt_str_op(seq->name.str, ==, "TEST");
+ tt_str_op(seq->comment.str, ==, "Comment 1");
+ tt_str_op(seq->seq.str, ==, "AGCT");
+ tt_str_op(seq->qual.str, ==, "IIII");
+ res = qes_seq_copy(copy, seq);
+ tt_int_op(res, ==, 0);
+ tt_str_op(copy->name.str, ==, "TEST");
+ tt_str_op(copy->comment.str, ==, "Comment 1");
+ tt_str_op(copy->seq.str, ==, "AGCT");
+ tt_str_op(copy->qual.str, ==, "IIII");
+ tt_int_op(qes_seq_copy(NULL, seq), ==, 1);
+ tt_int_op(qes_seq_copy(seq, NULL), ==, 1);
+ tt_int_op(qes_seq_copy(seq, seq), ==, 1);
+
+end:
+ qes_seq_destroy(seq);
+ qes_seq_destroy(copy);
+}
+
+static void
+test_qes_seq_fill_funcs(void *ptr)
+{
+#define CHECK_FILLING(submember, st, ln) \
+ seq = qes_seq_create(); \
+ tt_str_op(seq->submember.str, ==, ""); \
+ res = qes_seq_fill_ ##submember (seq, st, ln); \
+ tt_int_op(res, ==, 0); \
+ tt_str_op(seq->submember.str, ==, st); \
+ tt_int_op(seq->submember.len, ==, ln); \
+ tt_int_op(seq->submember.capacity, >=, ln); \
+ qes_seq_destroy(seq);
+#define CHECK_FILLING_FAIL(submember, st, ln) \
+ seq = qes_seq_create(); \
+ tt_str_op(seq->submember.str, ==, ""); \
+ res = qes_seq_fill_ ##submember (seq, st, ln); \
+ tt_int_op(res, ==, 1); \
+ tt_str_op(seq->submember.str, ==, ""); \
+ tt_int_op(seq->submember.len, ==, 0); \
+ qes_seq_destroy(seq);
+
+ struct qes_seq *seq = NULL;
+ int res = 0;
+ char *tmp = NULL;
+
+ (void) ptr;
+ /* These should all work pretty well */
+ CHECK_FILLING(name, "HWI_TEST", 8)
+ CHECK_FILLING(comment, "abc 123 comment", 15)
+ CHECK_FILLING(seq, "ACTG", 4)
+ CHECK_FILLING(qual, "IIII", 4)
+ /* These should all fail */
+ CHECK_FILLING_FAIL(name, NULL, 1)
+ CHECK_FILLING_FAIL(name, "BAD", 0)
+ CHECK_FILLING_FAIL(comment, NULL, 1)
+ CHECK_FILLING_FAIL(comment, "BAD", 0)
+ CHECK_FILLING_FAIL(seq, NULL, 1)
+ CHECK_FILLING_FAIL(seq, "BAD", 0)
+ CHECK_FILLING_FAIL(qual, NULL, 1)
+ CHECK_FILLING_FAIL(qual, "BAD", 0)
+ tt_int_op(qes_seq_fill_name(NULL, "BAD", 3), ==, 1);
+ tt_int_op(qes_seq_fill_comment(NULL, "BAD", 3), ==, 1);
+ tt_int_op(qes_seq_fill_seq(NULL, "BAD", 3), ==, 1);
+ tt_int_op(qes_seq_fill_qual(NULL, "BAD", 3), ==, 1);
+
+ /* Fill header */
+#define CHECK_FILL_HEADER(st, ln, nm, nmlen, com, comlen) \
+ tmp = strdup(st); \
+ seq = qes_seq_create(); \
+ tt_str_op(seq->name.str, ==, ""); \
+ tt_str_op(seq->comment.str, ==, ""); \
+ res = qes_seq_fill_header(seq, tmp, ln); \
+ tt_int_op(res, ==, 0); \
+ tt_str_op(seq->name.str, ==, nm); \
+ tt_int_op(seq->name.len, ==, nmlen); \
+ tt_int_op(seq->name.capacity, >=, nmlen); \
+ tt_str_op(seq->comment.str, ==, com); \
+ tt_int_op(seq->comment.len, ==, comlen); \
+ tt_int_op(seq->comment.capacity, >=, comlen); \
+ qes_seq_destroy(seq); \
+ free(tmp); \
+ tmp = NULL;
+ CHECK_FILL_HEADER("@HWI_TEST COMM\n", 15, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER("@HWI_TEST COMM\n", 0, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER("@HWI_TEST COMM \r\n", 17, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER("@HWI_TEST COMM", 14, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER(">HWI_TEST COMM", 14, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER("HWI_TEST COMM", 13, "HWI_TEST", 8, "COMM", 4)
+ CHECK_FILL_HEADER("@HWI_TEST", 9, "HWI_TEST", 8, "", 0)
+ CHECK_FILL_HEADER(">HWI_TEST", 9, "HWI_TEST", 8, "", 0)
+ CHECK_FILL_HEADER("HWI_TEST", 8, "HWI_TEST", 8, "", 0)
+ /* Check bad values */
+ seq = qes_seq_create();
+ tmp = strdup("BAD");
+ tt_int_op(qes_seq_fill_header(NULL, tmp, 3), ==, 1);
+ tt_int_op(qes_seq_fill_header(seq, NULL, 3), ==, 1);
+ qes_seq_destroy(seq);
+end:
+ if (tmp != NULL) {
+ free(tmp);
+ }
+ qes_seq_destroy(seq);
+#undef CHECK_FILLING
+#undef CHECK_FILLING_FAIL
+#undef CHECK_FILL_HEADER
+}
+
+
+struct testcase_t qes_seq_tests[] = {
+ { "qes_seq_create", test_qes_seq_create, 0, NULL, NULL},
+ { "qes_seq_create_no_qual", test_qes_seq_create_no_qual, 0, NULL, NULL},
+ { "qes_seq_create_no_qual_or_comment",
+ test_qes_seq_create_no_qual_or_comment, 0, NULL, NULL},
+ { "qes_seq_ok", test_qes_seq_ok, 0, NULL, NULL},
+ { "qes_seq_ok_no_comment", test_qes_seq_ok_no_comment, 0, NULL, NULL},
+ { "qes_seq_ok_no_qual", test_qes_seq_ok_no_qual, 0, NULL, NULL},
+ { "qes_seq_ok_no_comment_or_qual", test_qes_seq_ok_no_comment_or_qual, 0,
+ NULL, NULL},
+ { "qes_seq_destroy", test_qes_seq_destroy, 0, NULL, NULL},
+ { "qes_seq_fill", test_qes_seq_fill_funcs, 0, NULL, NULL},
+ { "qes_seq_copy", test_qes_seq_copy, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_seqfile.c b/src/libqes/test/test_seqfile.c
new file mode 100644
index 0000000..3639d82
--- /dev/null
+++ b/src/libqes/test/test_seqfile.c
@@ -0,0 +1,402 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_seqfile.c
+ *
+ * Description: Tests for the qes_seqfile module
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_seqfile.h>
+#include "kseq.h"
+
+
+#ifdef ZLIB_FOUND
+# include <zlib.h>
+ KSEQ_INIT(gzFile, gzread)
+#else
+# include <sys/stat.h>
+# include <fcntl.h>
+ KSEQ_INIT(int, read)
+#endif
+
+
+
+static void
+test_qes_seqfile_create(void *ptr)
+{
+ struct qes_seqfile *sf = NULL;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Test file opening for reading */
+ /* test opening a valid, unziped FASTQ */
+ fname = find_data_file("test.fastq");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ tt_ptr_op(sf, !=, NULL);
+ tt_ptr_op(sf->qf, !=, NULL);
+ tt_int_op(sf->qf->mode, ==, QES_FILE_MODE_READ);
+ tt_int_op(sf->n_records, ==, 0);
+ tt_int_op(sf->format, ==, FASTQ_FMT);
+ qes_seqfile_destroy(sf);
+ free(fname);
+ /* test opening a valid, unziped FASTA */
+ fname = find_data_file("test.fasta");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ tt_ptr_op(sf, !=, NULL);
+ tt_ptr_op(sf->qf, !=, NULL);
+ tt_int_op(sf->qf->mode, ==, QES_FILE_MODE_READ);
+ tt_int_op(sf->n_records, ==, 0);
+ tt_int_op(sf->format, ==, FASTA_FMT);
+ qes_seqfile_destroy(sf);
+ free(fname);
+ /* Test opening a file in transparent write mode */
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "wT");
+ QES_ZWRITE(sf->qf->fp, "ABCD", 4);
+ tt_ptr_op(sf, !=, NULL);
+ tt_ptr_op(sf->qf, !=, NULL);
+ tt_int_op(sf->qf->mode, ==, QES_FILE_MODE_WRITE);
+ tt_int_op(sf->n_records, ==, 0);
+ tt_int_op(access(fname, F_OK), ==, 0);
+ qes_seqfile_destroy(sf);
+ clean_writable_file(fname);
+ fname = NULL;
+ /* Test opening a file in write mode , acually zipping output */
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "w9");
+ tt_ptr_op(sf, !=, NULL);
+ tt_ptr_op(sf->qf, !=, NULL);
+ tt_int_op(sf->qf->mode, ==, QES_FILE_MODE_WRITE);
+ tt_int_op(sf->n_records, ==, 0);
+ tt_int_op(access(fname, F_OK), ==, 0);
+ qes_seqfile_destroy(sf);
+ clean_writable_file(fname);
+ fname = NULL;
+end:
+ qes_seqfile_destroy(sf);
+ if (fname != NULL) {
+ free(fname);
+ }
+}
+
+
+static void
+test_qes_seqfile_guess_format (void *ptr)
+{
+ struct qes_seqfile *sf = NULL;
+ int res = -1;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Test file opening for reading */
+ fname = find_data_file("test.fastq");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ /* test with a FASTQ file */
+ res = qes_seqfile_guess_format(sf);
+ tt_int_op(res, ==, FASTQ_FMT);
+ tt_int_op(sf->format, ==, FASTQ_FMT);
+ qes_seqfile_destroy(sf);
+ free(fname);
+ /* test with a FASTA file */
+ fname = find_data_file("test.fasta");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ res = qes_seqfile_guess_format(sf);
+ tt_int_op(res, ==, FASTA_FMT);
+ tt_int_op(sf->format, ==, FASTA_FMT);
+ qes_seqfile_destroy(sf);
+ free(fname);
+ fname = NULL;
+#ifdef ZLIB_FOUND
+ /* test with a gziped FASTQ file */
+ fname = find_data_file("test.fastq.gz");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ res = qes_seqfile_guess_format(sf);
+ tt_int_op(res, ==, FASTQ_FMT);
+ tt_int_op(sf->format, ==, FASTQ_FMT);
+ qes_seqfile_destroy(sf);
+#endif
+end:
+ qes_seqfile_destroy(sf);
+ if (fname != NULL) free(fname);
+}
+
+
+static void
+test_qes_seqfile_destroy (void *ptr)
+{
+ struct qes_seqfile *sf = NULL;
+ char *fname = NULL;
+
+ (void) ptr;
+ /* Test file opening for reading */
+ fname = find_data_file("test.fastq");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+ tt_ptr_op(sf, !=, NULL);
+ tt_assert(qes_seqfile_ok(sf));
+ qes_seqfile_destroy(sf);
+ tt_ptr_op(sf, ==, NULL);
+ tt_assert(!qes_seqfile_ok(sf));
+end:
+ qes_seqfile_destroy(sf);
+ if (fname != NULL) free(fname);
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: test_qes_seqfile_read
+Description: Tests the qes_seqfile_read function from qes_seqfile.c
+ *===========================================================================*/
+static void
+test_qes_seqfile_read (void *ptr)
+{
+ struct qes_seq *seq = qes_seq_create();
+ ssize_t res = 0;
+ struct qes_seqfile *sf = NULL;
+ char *fname = NULL;
+ /* Check a seq is empty */
+#define CHECK_SEQ_EMPTY \
+ tt_str_op(seq->name.str, ==, ""); \
+ tt_str_op(seq->comment.str, ==, ""); \
+ tt_str_op(seq->seq.str, ==, ""); \
+ tt_str_op(seq->qual.str, ==, "")
+ /* Check seq against the first known read */
+#define CHECK_SEQ_FIRST \
+ tt_str_op(seq->name.str, ==, first_fastq_read[0]); \
+ tt_str_op(seq->comment.str, ==, first_fastq_read[1]); \
+ tt_str_op(seq->seq.str, ==, first_fastq_read[2]); \
+ tt_str_op(seq->qual.str, ==, first_fastq_read[3])
+ /* Open, read, check & close a seqfile */
+#define CHECK_SEQFILE_READ(fn, expt_res, check_seq) \
+ fname = find_data_file(fn); \
+ tt_assert(fname != NULL); \
+ sf = qes_seqfile_create(fname, "r"); \
+ res = qes_seqfile_read(sf, seq); \
+ tt_int_op(res, ==, expt_res); \
+ check_seq; \
+ qes_seqfile_destroy(sf); \
+ free(fname); \
+ fname = NULL
+ /* Open, read, check & close a seqfile, forcing its filetype to FASTQ */
+#define CHECK_SEQFILE_READ_FORCE(fn, expt_res, check_seq) \
+ fname = find_data_file(fn); \
+ tt_assert(fname != NULL); \
+ sf = qes_seqfile_create(fname, "r"); \
+ qes_seqfile_set_format(sf, FASTQ_FMT); \
+ res = qes_seqfile_read(sf, seq); \
+ tt_int_op(res, ==, expt_res); \
+ check_seq; \
+ qes_seqfile_destroy(sf); \
+ free(fname); \
+ fname = NULL
+
+ (void) ptr;
+ /* Test file opening for reading */
+ CHECK_SEQFILE_READ("test.fastq", first_fastq_len, CHECK_SEQ_FIRST);
+ CHECK_SEQFILE_READ("test.fasta", 33,
+ tt_str_op(seq->name.str, ==, "HWI-ST960:105:D10GVACXX:2:1101:1122:2186");
+ tt_str_op(seq->comment.str, ==, "1:N:0: bcd:RPI8 seq:CACACTTGAATC");
+ tt_str_op(seq->seq.str, ==, "CACACTTGAATCCAGTTTAAAGTTAACTCATTG");
+ tt_int_op(seq->qual.len, ==, 0);
+ tt_str_op(seq->qual.str, ==, "")
+ );
+ CHECK_SEQFILE_READ("nocomment.fasta", 33,
+ tt_str_op(seq->name.str, ==, "HWI-ST960:105:D10GVACXX:2:1101:1122:2186");
+ tt_int_op(seq->comment.len, ==, 0);
+ tt_str_op(seq->comment.str, ==, "");
+ tt_str_op(seq->seq.str, ==, "CACACTTGAATCCAGTTTAAAGTTAACTCATTG");
+ tt_int_op(seq->qual.len, ==, 0);
+ tt_str_op(seq->qual.str, ==, "")
+ );
+ /* Test with bad fastqs, ensure all code paths are taken */
+ CHECK_SEQFILE_READ("loremipsum.txt", -2, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("bad_nohdr.fastq", -2, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("loremipsum.txt", -2, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ_FORCE("loremipsum.txt", -3, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("empty.fastq", -3, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("bad_noqual.fastq", -6, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("bad_noqualhdrchr.fastq", -5, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("bad_noqualhdreol.fastq", -5, CHECK_SEQ_EMPTY);
+ CHECK_SEQFILE_READ("bad_diff_lens.fastq", -7, CHECK_SEQ_EMPTY);
+ /* Check with bad params that it returns -2 */
+ res = qes_seqfile_read(NULL, seq);
+ tt_int_op(res, ==, -2);
+ res = qes_seqfile_read(sf, NULL);
+ tt_int_op(res, ==, -2);
+end:
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+ if (fname != NULL) {
+ free(fname);
+ }
+#undef CHECK_SEQ_EMPTY
+#undef CHECK_SEQFILE_READ
+}
+
+
+static void
+test_qes_seqfile_read_vs_kseq (void *ptr)
+{
+ struct qes_seq *seq = qes_seq_create();
+#ifdef ZLIB_FOUND
+ char *fname = find_data_file("test.fastq.gz");
+ gzFile fp = gzopen(fname, "r");
+#else
+ char *fname = find_data_file("test.fastq");
+ int fp = open(fname, O_RDONLY);
+#endif
+ struct qes_seqfile *sf = qes_seqfile_create(fname, "r");
+ kseq_t *kseq = kseq_init(fp);
+ ssize_t kseq_res = 0;
+ ssize_t my_res = 0;
+
+ (void) ptr;
+ tt_assert(fname != NULL);
+ while (1) {
+ my_res = qes_seqfile_read(sf, seq);
+ kseq_res = kseq_read(kseq);
+ tt_int_op(my_res, ==, kseq_res);
+ if (my_res < 1 || kseq_res < 1) {
+ /* EOF or error */
+ break;
+ }
+ tt_str_op(seq->name.str, ==, kseq->name.s);
+ tt_str_op(seq->comment.str, ==, kseq->comment.s);
+ tt_str_op(seq->seq.str, ==, kseq->seq.s);
+ tt_str_op(seq->qual.str, ==, kseq->qual.s);
+ }
+ my_res = qes_seqfile_read(sf, seq);
+ kseq_res = kseq_read(kseq);
+ tt_int_op(my_res, ==, kseq_res);
+ tt_int_op(my_res, ==, EOF);
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+ kseq_destroy(kseq);
+ kseq = NULL;
+#ifdef ZLIB_FOUND
+ gzclose(fp);
+#else
+ close(fp);
+#endif
+ free(fname);
+ /* Try again, with fasta */
+ seq = qes_seq_create();
+ fname = find_data_file("test.fasta");
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "r");
+#ifdef ZLIB_FOUND
+ fp = gzopen(fname, "r");
+#else
+ fp = open(fname, O_RDONLY);
+#endif
+ kseq = kseq_init(fp);
+ while (1) {
+ my_res = qes_seqfile_read(sf, seq);
+ kseq_res = kseq_read(kseq);
+ tt_int_op(my_res, ==, kseq_res);
+ if (my_res < 1 || kseq_res < 1) {
+ /* EOF or error */
+ break;
+ }
+ tt_str_op(seq->name.str, ==, kseq->name.s);
+ tt_str_op(seq->comment.str, ==, kseq->comment.s);
+ tt_str_op(seq->seq.str, ==, kseq->seq.s);
+ }
+end:
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+ if (kseq != NULL) kseq_destroy(kseq);
+ if (fname != NULL) free(fname);
+#ifdef ZLIB_FOUND
+ gzclose(fp);
+#else
+ close(fp);
+#endif
+}
+
+
+/*=== FUNCTION ============================================================*
+Name: test_qes_seqfile_write
+Description: Tests the qes_seqfile_write function from qes_seqfile.c
+ *===========================================================================*/
+static void
+test_qes_seqfile_write (void *ptr)
+{
+ struct qes_seq *seq = qes_seq_create();
+ size_t expt_bytes = 0;
+ ssize_t res = 0;
+ struct qes_seqfile *sf = NULL;
+ char *fname = NULL;
+ char *crc = NULL;
+
+ (void) ptr;
+ /* Make a seq to write */
+ qes_seq_fill_name(seq, "HWI-TEST", 8);
+ qes_seq_fill_comment(seq, "testseq 1 2 3", 13);
+ qes_seq_fill_seq(seq, "ACTCAATT", 8);
+ qes_seq_fill_qual(seq, "IIIIIIII", 8);
+ expt_bytes = 1 + 8 + 1 + 13 + 1 + /* @ + name + ' ' + comment + '\n' */
+ 8 + 1 + 2 + 8 + 1; /* seq + '\n' + "+\n" + qual + '\n' */
+ /* Test with a FASTQ seqfile */
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "wT");
+ qes_seqfile_set_format(sf, FASTQ_FMT);
+ res = qes_seqfile_write(sf, seq);
+ tt_int_op(res, ==, expt_bytes);
+ qes_seqfile_destroy(sf); /* Has to happen here to flush it */
+ crc = crc32_file(fname);
+ tt_str_op(crc, ==, "d4665941");
+ clean_writable_file(fname);
+ free(crc);
+ fname = NULL;
+ crc = NULL;
+ /* Test with a FASTA seqfile */
+ expt_bytes = 1 + 8 + 1 + 13 + 1 + /* @ + name + ' ' + comment + '\n' */
+ 8 + 1; /* seq + '\n'*/
+ fname = get_writable_file();
+ tt_assert(fname != NULL);
+ sf = qes_seqfile_create(fname, "wT");
+ qes_seqfile_set_format(sf, FASTA_FMT);
+ /* do the write */
+ res = qes_seqfile_write(sf, seq);
+ tt_int_op(res, ==, expt_bytes);
+ qes_seqfile_destroy(sf); /* Flush it */
+ crc = crc32_file(fname);
+ tt_str_op(crc, ==, "0a295c77");
+ clean_writable_file(fname);
+ fname = NULL;
+ /* Check with bad params that it returns -2 */
+ res = qes_seqfile_write(NULL, seq);
+ tt_int_op(res, ==, -2);
+ res = qes_seqfile_write(sf, NULL);
+ tt_int_op(res, ==, -2);
+end:
+ qes_seqfile_destroy(sf);
+ qes_seq_destroy(seq);
+ if (fname != NULL) free(fname);
+ if (crc != NULL) free(crc);
+}
+
+
+struct testcase_t qes_seqfile_tests[] = {
+ { "qes_seqfile_create", test_qes_seqfile_create, 0, NULL, NULL},
+ { "qes_seqfile_guess_format", test_qes_seqfile_guess_format, 0, NULL, NULL},
+ { "qes_seqfile_destroy", test_qes_seqfile_destroy, 0, NULL, NULL},
+ { "qes_seqfile_read_vs_kseq", test_qes_seqfile_read_vs_kseq, 0, NULL, NULL},
+ { "qes_seqfile_read", test_qes_seqfile_read, 0, NULL, NULL},
+ { "qes_seqfile_write", test_qes_seqfile_write, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_sequtil.c b/src/libqes/test/test_sequtil.c
new file mode 100644
index 0000000..bcf4a43
--- /dev/null
+++ b/src/libqes/test/test_sequtil.c
@@ -0,0 +1,51 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_sequtil.c
+ *
+ * Description: Tests for the sequtil module
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_sequtil.h>
+
+
+static void
+test_qes_sequtil_translate_codon (void *ptr)
+{
+ size_t iii;
+ size_t jjj;
+ char *cdn = NULL;
+ char aa = 0;
+
+ (void) ptr;
+ for (iii = 0; iii < n_codons; iii++) {
+ aa = qes_sequtil_translate_codon(codon_list[iii]);
+ tt_assert_op_type(aa, ==, aa_list[iii], char, "%c");
+ }
+ tt_int_op(qes_sequtil_translate_codon("XACACA"), ==, -1);
+ tt_int_op(qes_sequtil_translate_codon("A"), ==, -1);
+ tt_int_op(qes_sequtil_translate_codon(NULL), ==, -1);
+ /* Try with mutations */
+ for (iii = 0; iii < n_codons; iii++) {
+ for (jjj = 0; jjj < 3; jjj++) {
+ cdn = strdup(codon_list[iii]);
+ cdn[jjj] = 'N';
+ aa = qes_sequtil_translate_codon(cdn);
+ tt_assert_op_type(aa, ==, 'X', char, "%c");
+ free(cdn);
+ cdn = NULL;
+ }
+ }
+end:
+ if (cdn != NULL) free(cdn);
+}
+
+struct testcase_t qes_sequtil_tests[] = {
+ { "qes_sequtil_translate_codon", test_qes_sequtil_translate_codon, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/test_util.c b/src/libqes/test/test_util.c
new file mode 100644
index 0000000..f4c6da7
--- /dev/null
+++ b/src/libqes/test/test_util.c
@@ -0,0 +1,145 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_util.c
+ *
+ * Description: Test qes_util.c
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+#include <qes_util.h>
+
+
+/* Actual tests */
+static void
+test_qes_calloc(void *ptr)
+{
+ void *res = NULL;
+ const size_t bufsize = 1<<10;
+ unsigned char *zeros[1<<10];
+
+ (void) ptr;
+ memset(zeros, 0, bufsize);
+ /* This should work, and the buffer should be zero throughout */
+ res = qes_calloc(1, 1);
+ tt_ptr_op(res, !=, NULL);
+ tt_int_op(memcmp(res, zeros, 1), ==, 0);
+ free(res);
+ res = NULL;
+end:
+ if (res != NULL) free(res);
+}
+
+static void
+test_qes_malloc(void *ptr)
+{
+ void *res = NULL;
+
+ (void) ptr;
+ res = qes_malloc(1);
+ tt_ptr_op(res, !=, NULL);
+ free(res);
+ res = NULL;
+end:
+ if (res != NULL) free(res);
+}
+
+static void
+test_qes_realloc(void *ptr)
+{
+ char *res = NULL;
+ const char *str = "test";
+ char *dat = strdup(str);
+
+ (void) ptr;
+ /* Test resizing buffer */
+ res = qes_realloc(dat, 10);
+ dat = NULL;
+ tt_ptr_op(res, !=, NULL);
+ tt_int_op(memcmp(res, str, 5), ==, 0);
+ free(res);
+ res = NULL;
+end:
+ if (res != NULL) free(res);
+ if (dat != NULL) free(dat);
+}
+
+static void
+test_qes_free(void *ptr)
+{
+ char *dat = strdup("test");
+
+ (void) ptr;
+ /* Test freeing buffer */
+ tt_ptr_op(dat, !=, NULL);
+ qes_free(dat);
+ tt_ptr_op(dat, ==, NULL);
+ /* This free(NULL) should not fail */
+ qes_free(dat);
+ tt_ptr_op(dat, ==, NULL);
+end:
+ if (dat != NULL) free(dat);
+}
+
+static void
+test_qes_roundup32 (void *ptr)
+{
+ int32_t val = 3;
+ uint32_t uval = (1u<<31) - 1;
+
+ (void) ptr;
+ /* Signed */
+ tt_int_op(qes_roundup32(val), ==, 4);
+ val++;
+ tt_int_op(qes_roundup32(val), ==, 8);
+ val = 8;
+ tt_int_op(qes_roundup32(val), ==, 16);
+ val = 262143;
+ tt_int_op(qes_roundup32(val), ==, 262144);
+ /* Unsigned */
+ tt_int_op(qes_roundup32(uval), ==, 1u<<31);
+ uval++;
+ tt_int_op(qes_roundup32(uval), ==, 0);
+end:
+ ;
+}
+
+static void
+test_qes_roundup64 (void *ptr)
+{
+ int64_t val = 3;
+ uint64_t uval = (1llu<<63) - 1;
+
+ (void) ptr;
+ /* Signed */
+ tt_int_op(qes_roundup64(val), ==, 4);
+ val = 4;
+ tt_int_op(qes_roundup64(val), ==, 8);
+ val = 8;
+ tt_int_op(qes_roundup64(val), ==, 16);
+ val = 262143llu;
+ tt_int_op(qes_roundup64(val), ==, 262144);
+ /* Unsigned */
+ tt_assert(qes_roundup64(uval) == 1llu<<63);
+ uval = 1llu<<62;
+ tt_assert(qes_roundup64(uval) == 1llu<<63);
+ uval = 63llu;
+ tt_assert(qes_roundup64(uval) - 2 == 62llu);
+end:
+ ;
+}
+
+
+struct testcase_t qes_util_tests[] = {
+ { "qes_calloc", test_qes_calloc, 0, NULL, NULL},
+ { "qes_malloc", test_qes_malloc, 0, NULL, NULL},
+ { "qes_realloc", test_qes_realloc, 0, NULL, NULL},
+ { "qes_free", test_qes_free, 0, NULL, NULL},
+ { "qes_roundup32", test_qes_roundup32, 0, NULL, NULL},
+ { "qes_roundup64", test_qes_roundup64, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/testdata.c b/src/libqes/test/testdata.c
new file mode 100644
index 0000000..4a66c85
--- /dev/null
+++ b/src/libqes/test/testdata.c
@@ -0,0 +1,144 @@
+/*
+ * ============================================================================
+ *
+ * Filename: testdata.c
+ *
+ * Description: Data for tests
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "testdata.h"
+
+
+const size_t n_loremipsum_lines = 11;
+const size_t loremipsum_fsize = 80+76+80+75+80+79+77+75+69+1+20;
+const size_t loremipsum_line_lens[] = {
+ 80, 76, 80, 75, 80, 79, 77, 75, 69, 1, 20
+};
+const char *loremipsum_lines[] = {
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ornare tortor et\n",
+ "rhoncus iaculis. Sed suscipit, arcu nec elementum vestibulum, tortor tortor\n",
+ "dictum dui, eu sodales magna orci eu libero. Cras commodo, ligula tempor auctor\n",
+ "vulputate, eros urna gravida eros, eget congue leo quam quis mi. Curabitur\n",
+ "luctus augue nibh, eget vehicula augue commodo eget. Donec condimentum molestie\n",
+ "adipiscing. In non purus lacus. Nam nec mollis mauris. Donec rhoncus, diam sit\n",
+ "amet rhoncus viverra, lectus risus tincidunt ipsum, in dignissim justo purus\n",
+ "eget enim. Fusce congue nulla egestas est auctor faucibus. Integer feugiat\n",
+ "molestie leo, a interdum neque pretium nec. Etiam sit amet nibh leo.\n",
+ "\n",
+ "End of lorem ipsum.\n",
+};
+const char *first_fastq_read[] = {
+ "HWI-ST960:105:D10GVACXX:2:1101:1151:2158",
+ "1:N:0: bcd:RPI9 seq:CACGATCAGATC",
+ "CACGATCAGATCAANGACATTGAATCTATATGT",
+ "JJJJJJJIJHIJCC#4ADFFHHHGHJJJJIJJJ",
+};
+const size_t first_fastq_len = 33;
+
+
+const size_t n_codons = 125;
+
+const char *codon_list[] = {
+ "AAA", "AAC", "AAG", "AAT", "AAU",
+ "ACA", "ACC", "ACG", "ACT", "ACU",
+ "AGA", "AGC", "AGG", "AGT", "AGU",
+ "ATA", "ATC", "ATG", "ATT", "ATU",
+ "AUA", "AUC", "AUG", "AUT", "AUU",
+ "CAA", "CAC", "CAG", "CAT", "CAU",
+ "CCA", "CCC", "CCG", "CCT", "CCU",
+ "CGA", "CGC", "CGG", "CGT", "CGU",
+ "CTA", "CTC", "CTG", "CTT", "CTU",
+ "CUA", "CUC", "CUG", "CUT", "CUU",
+ "GAA", "GAC", "GAG", "GAT", "GAU",
+ "GCA", "GCC", "GCG", "GCT", "GCU",
+ "GGA", "GGC", "GGG", "GGT", "GGU",
+ "GTA", "GTC", "GTG", "GTT", "GTU",
+ "GUA", "GUC", "GUG", "GUT", "GUU",
+ "TAA", "TAC", "TAG", "TAT", "TAU",
+ "TCA", "TCC", "TCG", "TCT", "TCU",
+ "TGA", "TGC", "TGG", "TGT", "TGU",
+ "TTA", "TTC", "TTG", "TTT", "TTU",
+ "TUA", "TUC", "TUG", "TUT", "TUU",
+ "UAA", "UAC", "UAG", "UAT", "UAU",
+ "UCA", "UCC", "UCG", "UCT", "UCU",
+ "UGA", "UGC", "UGG", "UGT", "UGU",
+ "UTA", "UTC", "UTG", "UTT", "UTU",
+ "UUA", "UUC", "UUG", "UUT", "UUU",
+};
+
+const char aa_list[] = {
+ 'K', 'N', 'K', 'N', 'N',
+ 'T', 'T', 'T', 'T', 'T',
+ 'R', 'S', 'R', 'S', 'S',
+ 'I', 'I', 'M', 'I', 'I',
+ 'I', 'I', 'M', 'I', 'I',
+ 'Q', 'H', 'Q', 'H', 'H',
+ 'P', 'P', 'P', 'P', 'P',
+ 'R', 'R', 'R', 'R', 'R',
+ 'L', 'L', 'L', 'L', 'L',
+ 'L', 'L', 'L', 'L', 'L',
+ 'E', 'D', 'E', 'D', 'D',
+ 'A', 'A', 'A', 'A', 'A',
+ 'G', 'G', 'G', 'G', 'G',
+ 'V', 'V', 'V', 'V', 'V',
+ 'V', 'V', 'V', 'V', 'V',
+ '*', 'Y', '*', 'Y', 'Y',
+ 'S', 'S', 'S', 'S', 'S',
+ '*', 'C', 'W', 'C', 'C',
+ 'L', 'F', 'L', 'F', 'F',
+ 'L', 'F', 'L', 'F', 'F',
+ '*', 'Y', '*', 'Y', 'Y',
+ 'S', 'S', 'S', 'S', 'S',
+ '*', 'C', 'W', 'C', 'C',
+ 'L', 'F', 'L', 'F', 'F',
+ 'L', 'F', 'L', 'F', 'F',
+};
+
+void
+test_data_files (void *ptr)
+{
+ char *fname = NULL;
+ char *crc_res = NULL;
+
+ (void) ptr;
+ fname = find_data_file("loremipsum.txt");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "9f20f7ec");
+ free(fname);
+ free(crc_res);
+ fname = find_data_file("loremipsum.txt.gz");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "4e42dcb2");
+ free(fname);
+ free(crc_res);
+ fname = find_data_file("test.fastq");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "c32cc3c0");
+ free(fname);
+ free(crc_res);
+ fname = find_data_file("test.fasta");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "3de06bb6");
+ free(fname);
+ free(crc_res);
+ fname = find_data_file("test.fastq.gz");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "ba1206ee");
+ free(fname);
+ free(crc_res);
+ fname = find_data_file("test.fastq.bz2");
+ crc_res = crc32_file(fname);
+ tt_str_op(crc_res, ==, "c8b66d33");
+end:
+ free(fname);
+ free(crc_res);
+}
+
+struct testcase_t data_tests[] = {
+ { "data_files", test_data_files, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/src/libqes/test/testdata.h b/src/libqes/test/testdata.h
new file mode 100644
index 0000000..48c374f
--- /dev/null
+++ b/src/libqes/test/testdata.h
@@ -0,0 +1,49 @@
+/*
+ * ============================================================================
+ *
+ * Filename: testdata.h
+ *
+ * Description: Data for tests
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef TESTDATA_H
+#define TESTDATA_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* TinyTest */
+#include "tinytest.h"
+#include "tinytest_macros.h"
+#include "testdata.h"
+#include "helpers.h"
+
+
+extern const size_t n_loremipsum_lines;
+extern const size_t loremipsum_fsize;
+extern const size_t loremipsum_line_lens[];
+extern const char *loremipsum_lines[];
+extern const char *first_fastq_read[];
+extern const size_t first_fastq_len;
+extern struct testcase_t data_tests[];
+extern const size_t n_codons;
+extern const char *codon_list[];
+extern const char aa_list[];
+
+void test_data_files (void *ptr);
+
+#endif /* TESTDATA_H */
diff --git a/src/libqes/test/tests.h b/src/libqes/test/tests.h
new file mode 100644
index 0000000..3d3eafa
--- /dev/null
+++ b/src/libqes/test/tests.h
@@ -0,0 +1,57 @@
+/*
+ * ============================================================================
+ *
+ * Filename: tests.h
+ *
+ * Description: Tests for libqes
+ * License: GPLv3+
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef TESTS_H
+#define TESTS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* TinyTest */
+#include "tinytest.h"
+#include "tinytest_macros.h"
+#include "testdata.h"
+#include "helpers.h"
+
+#define QES_DEFAULT_ERR_FN errnil
+#define QES_EXIT_FN (void)
+#include <qes_util.h>
+
+
+/* test_util tests */
+extern struct testcase_t qes_util_tests[];
+/* test_match tests */
+extern struct testcase_t qes_match_tests[];
+/* test_qes_file tests */
+extern struct testcase_t qes_file_tests[];
+/* test_seqfile tests */
+extern struct testcase_t qes_seqfile_tests[];
+/* test_seq tests */
+extern struct testcase_t qes_seq_tests[];
+/* test_sequtil tests */
+extern struct testcase_t qes_sequtil_tests[];
+/* test_log tests */
+extern struct testcase_t qes_log_tests[];
+/* test_helpers tests */
+extern struct testcase_t helper_tests[];
+
+#endif /* TESTS_H */
diff --git a/src/libqes/test/tinytest/tinytest.c b/src/libqes/test/tinytest/tinytest.c
new file mode 100644
index 0000000..3a8e331
--- /dev/null
+++ b/src/libqes/test/tinytest/tinytest.c
@@ -0,0 +1,493 @@
+/* tinytest.c -- Copyright 2009-2012 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef TINYTEST_LOCAL
+#include "tinytest_local.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifndef NO_FORKING
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif
+
+#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
+#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
+/* Workaround for a stupid bug in OSX 10.6 */
+#define FORK_BREAKS_GCOV
+#include <vproc.h>
+#endif
+#endif
+
+#endif /* !NO_FORKING */
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+#include "tinytest.h"
+#include "tinytest_macros.h"
+
+#define LONGEST_TEST_NAME 16384
+
+static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/
+static int n_ok = 0; /**< Number of tests that have passed */
+static int n_bad = 0; /**< Number of tests that have failed. */
+static int n_skipped = 0; /**< Number of tests that have been skipped. */
+
+static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/
+static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */
+static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */
+const char *verbosity_flag = "";
+
+const struct testlist_alias_t *cfg_aliases=NULL;
+
+enum outcome { SKIP=2, OK=1, FAIL=0 };
+static enum outcome cur_test_outcome = 0;
+const char *cur_test_prefix = NULL; /**< prefix of the current test group */
+/** Name of the current test, if we haven't logged is yet. Used for --quiet */
+const char *cur_test_name = NULL;
+
+#ifdef _WIN32
+/* Copy of argv[0] for win32. */
+static char commandname[MAX_PATH+1];
+#endif
+
+static void usage(struct testgroup_t *groups, int list_groups)
+ __attribute__((noreturn));
+static int process_test_option(struct testgroup_t *groups, const char *test);
+
+static enum outcome
+testcase_run_bare_(const struct testcase_t *testcase)
+{
+ void *env = NULL;
+ int outcome;
+ if (testcase->setup) {
+ env = testcase->setup->setup_fn(testcase);
+ if (!env)
+ return FAIL;
+ else if (env == (void*)TT_SKIP)
+ return SKIP;
+ }
+
+ cur_test_outcome = OK;
+ testcase->fn(env);
+ outcome = cur_test_outcome;
+
+ if (testcase->setup) {
+ if (testcase->setup->cleanup_fn(testcase, env) == 0)
+ outcome = FAIL;
+ }
+
+ return outcome;
+}
+
+#define MAGIC_EXITCODE 42
+
+#ifndef NO_FORKING
+
+static enum outcome
+testcase_run_forked_(const struct testgroup_t *group,
+ const struct testcase_t *testcase)
+{
+#ifdef _WIN32
+ /* Fork? On Win32? How primitive! We'll do what the smart kids do:
+ we'll invoke our own exe (whose name we recall from the command
+ line) with a command line that tells it to run just the test we
+ want, and this time without forking.
+
+ (No, threads aren't an option. The whole point of forking is to
+ share no state between tests.)
+ */
+ int ok;
+ char buffer[LONGEST_TEST_NAME+256];
+ STARTUPINFOA si;
+ PROCESS_INFORMATION info;
+ DWORD exitcode;
+
+ if (!in_tinytest_main) {
+ printf("\nERROR. On Windows, testcase_run_forked_ must be"
+ " called from within tinytest_main.\n");
+ abort();
+ }
+ if (opt_verbosity>0)
+ printf("[forking] ");
+
+ snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s",
+ commandname, verbosity_flag, group->prefix, testcase->name);
+
+ memset(&si, 0, sizeof(si));
+ memset(&info, 0, sizeof(info));
+ si.cb = sizeof(si);
+
+ ok = CreateProcessA(commandname, buffer, NULL, NULL, 0,
+ 0, NULL, NULL, &si, &info);
+ if (!ok) {
+ printf("CreateProcess failed!\n");
+ return 0;
+ }
+ WaitForSingleObject(info.hProcess, INFINITE);
+ GetExitCodeProcess(info.hProcess, &exitcode);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+ if (exitcode == 0)
+ return OK;
+ else if (exitcode == MAGIC_EXITCODE)
+ return SKIP;
+ else
+ return FAIL;
+#else
+ int outcome_pipe[2];
+ pid_t pid;
+ (void)group;
+
+ if (pipe(outcome_pipe))
+ perror("opening pipe");
+
+ if (opt_verbosity>0)
+ printf("[forking] ");
+ pid = fork();
+#ifdef FORK_BREAKS_GCOV
+ vproc_transaction_begin(0);
+#endif
+ if (!pid) {
+ /* child. */
+ int test_r, write_r;
+ char b[1];
+ close(outcome_pipe[0]);
+ test_r = testcase_run_bare_(testcase);
+ assert(0<=(int)test_r && (int)test_r<=2);
+ b[0] = "NYS"[test_r];
+ write_r = (int)write(outcome_pipe[1], b, 1);
+ if (write_r != 1) {
+ perror("write outcome to pipe");
+ exit(1);
+ }
+ exit(0);
+ return FAIL; /* unreachable */
+ } else {
+ /* parent */
+ int status, r;
+ char b[1];
+ /* Close this now, so that if the other side closes it,
+ * our read fails. */
+ close(outcome_pipe[1]);
+ r = (int)read(outcome_pipe[0], b, 1);
+ if (r == 0) {
+ printf("[Lost connection!] ");
+ return 0;
+ } else if (r != 1) {
+ perror("read outcome from pipe");
+ }
+ waitpid(pid, &status, 0);
+ close(outcome_pipe[0]);
+ return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL);
+ }
+#endif
+}
+
+#endif /* !NO_FORKING */
+
+int
+testcase_run_one(const struct testgroup_t *group,
+ const struct testcase_t *testcase)
+{
+ enum outcome outcome;
+
+ if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) {
+ if (opt_verbosity>0)
+ printf("%s%s: %s\n",
+ group->prefix, testcase->name,
+ (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED");
+ ++n_skipped;
+ return SKIP;
+ }
+
+ if (opt_verbosity>0 && !opt_forked) {
+ printf("%s%s: ", group->prefix, testcase->name);
+ } else {
+ if (opt_verbosity==0) printf(".");
+ cur_test_prefix = group->prefix;
+ cur_test_name = testcase->name;
+ }
+
+#ifndef NO_FORKING
+ if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) {
+ outcome = testcase_run_forked_(group, testcase);
+ } else {
+#else
+ {
+#endif
+ outcome = testcase_run_bare_(testcase);
+ }
+
+ if (outcome == OK) {
+ ++n_ok;
+ if (opt_verbosity>0 && !opt_forked)
+ puts(opt_verbosity==1?"OK":"");
+ } else if (outcome == SKIP) {
+ ++n_skipped;
+ if (opt_verbosity>0 && !opt_forked)
+ puts("SKIPPED");
+ } else {
+ ++n_bad;
+ if (!opt_forked)
+ printf("\n [%s FAILED]\n", testcase->name);
+ }
+
+ if (opt_forked) {
+ exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1));
+ return 1; /* unreachable */
+ } else {
+ return (int)outcome;
+ }
+}
+
+int
+tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigned long flag)
+{
+ int i, j;
+ size_t length = LONGEST_TEST_NAME;
+ char fullname[LONGEST_TEST_NAME];
+ int found=0;
+ if (strstr(arg, ".."))
+ length = strstr(arg,"..")-arg;
+ for (i=0; groups[i].prefix; ++i) {
+ for (j=0; groups[i].cases[j].name; ++j) {
+ struct testcase_t *testcase = &groups[i].cases[j];
+ snprintf(fullname, sizeof(fullname), "%s%s",
+ groups[i].prefix, testcase->name);
+ if (!flag) { /* Hack! */
+ printf(" %s", fullname);
+ if (testcase->flags & TT_OFF_BY_DEFAULT)
+ puts(" (Off by default)");
+ else if (testcase->flags & TT_SKIP)
+ puts(" (DISABLED)");
+ else
+ puts("");
+ }
+ if (!strncmp(fullname, arg, length)) {
+ if (set)
+ testcase->flags |= flag;
+ else
+ testcase->flags &= ~flag;
+ ++found;
+ }
+ }
+ }
+ return found;
+}
+
+static void
+usage(struct testgroup_t *groups, int list_groups)
+{
+ puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
+ puts(" Specify tests by name, or using a prefix ending with '..'");
+ puts(" To skip a test, prefix its name with a colon.");
+ puts(" To enable a disabled test, prefix its name with a plus.");
+ puts(" Use --list-tests for a list of tests.");
+ if (list_groups) {
+ puts("Known tests are:");
+ tinytest_set_flag_(groups, "..", 1, 0);
+ }
+ exit(0);
+}
+
+static int
+process_test_alias(struct testgroup_t *groups, const char *test)
+{
+ int i, j, n, r;
+ for (i=0; cfg_aliases && cfg_aliases[i].name; ++i) {
+ if (!strcmp(cfg_aliases[i].name, test)) {
+ n = 0;
+ for (j = 0; cfg_aliases[i].tests[j]; ++j) {
+ r = process_test_option(groups, cfg_aliases[i].tests[j]);
+ if (r<0)
+ return -1;
+ n += r;
+ }
+ return n;
+ }
+ }
+ printf("No such test alias as @%s!",test);
+ return -1;
+}
+
+static int
+process_test_option(struct testgroup_t *groups, const char *test)
+{
+ int flag = TT_ENABLED_;
+ int n = 0;
+ if (test[0] == '@') {
+ return process_test_alias(groups, test + 1);
+ } else if (test[0] == ':') {
+ ++test;
+ flag = TT_SKIP;
+ } else if (test[0] == '+') {
+ ++test;
+ ++n;
+ if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) {
+ printf("No such test as %s!\n", test);
+ return -1;
+ }
+ } else {
+ ++n;
+ }
+ if (!tinytest_set_flag_(groups, test, 1, flag)) {
+ printf("No such test as %s!\n", test);
+ return -1;
+ }
+ return n;
+}
+
+void
+tinytest_set_aliases(const struct testlist_alias_t *aliases)
+{
+ cfg_aliases = aliases;
+}
+
+int
+tinytest_main(int c, const char **v, struct testgroup_t *groups)
+{
+ int i, j, n=0;
+
+#ifdef _WIN32
+ const char *sp = strrchr(v[0], '.');
+ const char *extension = "";
+ if (!sp || stricmp(sp, ".exe"))
+ extension = ".exe"; /* Add an exe so CreateProcess will work */
+ snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension);
+ commandname[MAX_PATH]='\0';
+#endif
+ for (i=1; i<c; ++i) {
+ if (v[i][0] == '-') {
+ if (!strcmp(v[i], "--RUNNING-FORKED")) {
+ opt_forked = 1;
+ } else if (!strcmp(v[i], "--no-fork")) {
+ opt_nofork = 1;
+ } else if (!strcmp(v[i], "--quiet")) {
+ opt_verbosity = -1;
+ verbosity_flag = "--quiet";
+ } else if (!strcmp(v[i], "--verbose")) {
+ opt_verbosity = 2;
+ verbosity_flag = "--verbose";
+ } else if (!strcmp(v[i], "--terse")) {
+ opt_verbosity = 0;
+ verbosity_flag = "--terse";
+ } else if (!strcmp(v[i], "--help")) {
+ usage(groups, 0);
+ } else if (!strcmp(v[i], "--list-tests")) {
+ usage(groups, 1);
+ } else {
+ printf("Unknown option %s. Try --help\n",v[i]);
+ return -1;
+ }
+ } else {
+ int r = process_test_option(groups, v[i]);
+ if (r<0)
+ return -1;
+ n += r;
+ }
+ }
+ if (!n)
+ tinytest_set_flag_(groups, "..", 1, TT_ENABLED_);
+
+#ifdef _IONBF
+ setvbuf(stdout, NULL, _IONBF, 0);
+#endif
+
+ ++in_tinytest_main;
+ for (i=0; groups[i].prefix; ++i)
+ for (j=0; groups[i].cases[j].name; ++j)
+ if (groups[i].cases[j].flags & TT_ENABLED_)
+ testcase_run_one(&groups[i],
+ &groups[i].cases[j]);
+
+ --in_tinytest_main;
+
+ if (opt_verbosity==0)
+ puts("");
+
+ if (n_bad)
+ printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad,
+ n_bad+n_ok,n_skipped);
+ else if (opt_verbosity >= 1)
+ printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped);
+
+ return (n_bad == 0) ? 0 : 1;
+}
+
+int
+tinytest_get_verbosity_(void)
+{
+ return opt_verbosity;
+}
+
+void
+tinytest_set_test_failed_(void)
+{
+ if (opt_verbosity <= 0 && cur_test_name) {
+ if (opt_verbosity==0) puts("");
+ printf("%s%s: ", cur_test_prefix, cur_test_name);
+ cur_test_name = NULL;
+ }
+ cur_test_outcome = 0;
+}
+
+void
+tinytest_set_test_skipped_(void)
+{
+ if (cur_test_outcome==OK)
+ cur_test_outcome = SKIP;
+}
+
+char *
+tinytest_format_hex_(const void *val_, unsigned long len)
+{
+ const unsigned char *val = val_;
+ char *result, *cp;
+ size_t i;
+
+ if (!val)
+ return strdup("null");
+ if (!(result = malloc(len*2+1)))
+ return strdup("<allocation failure>");
+ cp = result;
+ for (i=0;i<len;++i) {
+ *cp++ = "0123456789ABCDEF"[val[i] >> 4];
+ *cp++ = "0123456789ABCDEF"[val[i] & 0x0f];
+ }
+ *cp = 0;
+ return result;
+}
diff --git a/src/libqes/test/tinytest/tinytest.h b/src/libqes/test/tinytest/tinytest.h
new file mode 100644
index 0000000..ed07b26
--- /dev/null
+++ b/src/libqes/test/tinytest/tinytest.h
@@ -0,0 +1,100 @@
+/* tinytest.h -- Copyright 2009-2012 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TINYTEST_H_INCLUDED_
+#define TINYTEST_H_INCLUDED_
+
+/** Flag for a test that needs to run in a subprocess. */
+#define TT_FORK (1<<0)
+/** Runtime flag for a test we've decided to skip. */
+#define TT_SKIP (1<<1)
+/** Internal runtime flag for a test we've decided to run. */
+#define TT_ENABLED_ (1<<2)
+/** Flag for a test that's off by default. */
+#define TT_OFF_BY_DEFAULT (1<<3)
+/** If you add your own flags, make them start at this point. */
+#define TT_FIRST_USER_FLAG (1<<4)
+
+typedef void (*testcase_fn)(void *);
+
+struct testcase_t;
+
+/** Functions to initialize/teardown a structure for a testcase. */
+struct testcase_setup_t {
+ /** Return a new structure for use by a given testcase. */
+ void *(*setup_fn)(const struct testcase_t *);
+ /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */
+ int (*cleanup_fn)(const struct testcase_t *, void *);
+};
+
+/** A single test-case that you can run. */
+struct testcase_t {
+ const char *name; /**< An identifier for this case. */
+ testcase_fn fn; /**< The function to run to implement this case. */
+ unsigned long flags; /**< Bitfield of TT_* flags. */
+ const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/
+ void *setup_data; /**< Extra data usable by setup function */
+};
+#define END_OF_TESTCASES { NULL, NULL, 0, NULL, NULL }
+
+/** A group of tests that are selectable together. */
+struct testgroup_t {
+ const char *prefix; /**< Prefix to prepend to testnames. */
+ struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */
+};
+#define END_OF_GROUPS { NULL, NULL}
+
+struct testlist_alias_t {
+ const char *name;
+ const char **tests;
+};
+#define END_OF_ALIASES { NULL, NULL }
+
+/** Implementation: called from a test to indicate failure, before logging. */
+void tinytest_set_test_failed_(void);
+/** Implementation: called from a test to indicate that we're skipping. */
+void tinytest_set_test_skipped_(void);
+/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */
+int tinytest_get_verbosity_(void);
+/** Implementation: Set a flag on tests matching a name; returns number
+ * of tests that matched. */
+int tinytest_set_flag_(struct testgroup_t *, const char *, int set, unsigned long);
+/** Implementation: Put a chunk of memory into hex. */
+char *tinytest_format_hex_(const void *, unsigned long);
+
+/** Set all tests in 'groups' matching the name 'named' to be skipped. */
+#define tinytest_skip(groups, named) \
+ tinytest_set_flag_(groups, named, 1, TT_SKIP)
+
+/** Run a single testcase in a single group. */
+int testcase_run_one(const struct testgroup_t *,const struct testcase_t *);
+
+void tinytest_set_aliases(const struct testlist_alias_t *aliases);
+
+/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups,
+ as selected from the command line. */
+int tinytest_main(int argc, const char **argv, struct testgroup_t *groups);
+
+#endif
diff --git a/src/libqes/test/tinytest/tinytest_macros.h b/src/libqes/test/tinytest/tinytest_macros.h
new file mode 100644
index 0000000..c3728d1
--- /dev/null
+++ b/src/libqes/test/tinytest/tinytest_macros.h
@@ -0,0 +1,199 @@
+/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TINYTEST_MACROS_H_INCLUDED_
+#define TINYTEST_MACROS_H_INCLUDED_
+
+/* Helpers for defining statement-like macros */
+#define TT_STMT_BEGIN do {
+#define TT_STMT_END } while (0)
+
+/* Redefine this if your test functions want to abort with something besides
+ * "goto end;" */
+#ifndef TT_EXIT_TEST_FUNCTION
+#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END
+#endif
+
+/* Redefine this if you want to note success/failure in some different way. */
+#ifndef TT_DECLARE
+#define TT_DECLARE(prefix, args) \
+ TT_STMT_BEGIN \
+ printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \
+ printf args ; \
+ TT_STMT_END
+#endif
+
+/* Announce a failure. Args are parenthesized printf args. */
+#define TT_GRIPE(args) TT_DECLARE("FAIL", args)
+
+/* Announce a non-failure if we're verbose. */
+#define TT_BLATHER(args) \
+ TT_STMT_BEGIN \
+ if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \
+ TT_STMT_END
+
+#define TT_DIE(args) \
+ TT_STMT_BEGIN \
+ tinytest_set_test_failed_(); \
+ TT_GRIPE(args); \
+ TT_EXIT_TEST_FUNCTION; \
+ TT_STMT_END
+
+#define TT_FAIL(args) \
+ TT_STMT_BEGIN \
+ tinytest_set_test_failed_(); \
+ TT_GRIPE(args); \
+ TT_STMT_END
+
+/* Fail and abort the current test for the reason in msg */
+#define tt_abort_printf(msg) TT_DIE(msg)
+#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno))
+#define tt_abort_msg(msg) TT_DIE(("%s", msg))
+#define tt_abort() TT_DIE(("%s", "(Failed.)"))
+
+/* Fail but do not abort the current test for the reason in msg. */
+#define tt_failprint_f(msg) TT_FAIL(msg)
+#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno))
+#define tt_fail_msg(msg) TT_FAIL(("%s", msg))
+#define tt_fail() TT_FAIL(("%s", "(Failed.)"))
+
+/* End the current test, and indicate we are skipping it. */
+#define tt_skip() \
+ TT_STMT_BEGIN \
+ tinytest_set_test_skipped_(); \
+ TT_EXIT_TEST_FUNCTION; \
+ TT_STMT_END
+
+#define tt_want_(b, msg, fail) \
+ TT_STMT_BEGIN \
+ if (!(b)) { \
+ tinytest_set_test_failed_(); \
+ TT_GRIPE(("%s",msg)); \
+ fail; \
+ } else { \
+ TT_BLATHER(("%s",msg)); \
+ } \
+ TT_STMT_END
+
+/* Assert b, but do not stop the test if b fails. Log msg on failure. */
+#define tt_want_msg(b, msg) \
+ tt_want_(b, msg, );
+
+/* Assert b and stop the test if b fails. Log msg on failure. */
+#define tt_assert_msg(b, msg) \
+ tt_want_(b, msg, TT_EXIT_TEST_FUNCTION);
+
+/* Assert b, but do not stop the test if b fails. */
+#define tt_want(b) tt_want_msg( (b), "want("#b")")
+/* Assert b, and stop the test if b fails. */
+#define tt_assert(b) tt_assert_msg((b), "assert("#b")")
+
+#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \
+ setup_block,cleanup_block,die_on_fail) \
+ TT_STMT_BEGIN \
+ type val1_ = (a); \
+ type val2_ = (b); \
+ int tt_status_ = (test); \
+ if (!tt_status_ || tinytest_get_verbosity_()>1) { \
+ printf_type print_; \
+ printf_type print1_; \
+ printf_type print2_; \
+ type value_ = val1_; \
+ setup_block; \
+ print1_ = print_; \
+ value_ = val2_; \
+ setup_block; \
+ print2_ = print_; \
+ TT_DECLARE(tt_status_?" OK":"FAIL", \
+ ("assert(%s): "printf_fmt" vs "printf_fmt, \
+ str_test, print1_, print2_)); \
+ print_ = print1_; \
+ cleanup_block; \
+ print_ = print2_; \
+ cleanup_block; \
+ if (!tt_status_) { \
+ tinytest_set_test_failed_(); \
+ die_on_fail ; \
+ } \
+ } \
+ TT_STMT_END
+
+#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \
+ tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \
+ {print_=value_;},{},die_on_fail)
+
+#define tt_assert_test_type_opt(a,b,str_test,type,test,fmt,die_on_fail) \
+ tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \
+ {print_=value_?value_:"<NULL>";},{},die_on_fail)
+
+/* Helper: assert that a op b, when cast to type. Format the values with
+ * printf format fmt on failure. */
+#define tt_assert_op_type(a,op,b,type,fmt) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \
+ TT_EXIT_TEST_FUNCTION)
+
+#define tt_int_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \
+ "%ld",TT_EXIT_TEST_FUNCTION)
+
+#define tt_uint_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
+ (val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION)
+
+#define tt_ptr_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \
+ (val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION)
+
+#define tt_str_op(a,op,b) \
+ tt_assert_test_type_opt(a,b,#a" "#op" "#b,const char *, \
+ (val1_ && val2_ && strcmp(val1_,val2_) op 0),"<%s>", \
+ TT_EXIT_TEST_FUNCTION)
+
+#define tt_mem_op(expr1, op, expr2, len) \
+ tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \
+ const void *, \
+ (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \
+ char *, "%s", \
+ { print_ = tinytest_format_hex_(value_, (len)); }, \
+ { if (print_) free(print_); }, \
+ TT_EXIT_TEST_FUNCTION \
+ );
+
+#define tt_want_int_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0)
+
+#define tt_want_uint_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
+ (val1_ op val2_),"%lu",(void)0)
+
+#define tt_want_ptr_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \
+ (val1_ op val2_),"%p",(void)0)
+
+#define tt_want_str_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \
+ (strcmp(val1_,val2_) op 0),"<%s>",(void)0)
+
+#endif
diff --git a/src/libqes/util/make_codon_list.py b/src/libqes/util/make_codon_list.py
new file mode 100644
index 0000000..0611413
--- /dev/null
+++ b/src/libqes/util/make_codon_list.py
@@ -0,0 +1,38 @@
+from Bio.Data import CodonTable
+
+nts = "ACGTU"
+codons = []
+aas = []
+codon_tab = CodonTable.generic_by_name["Standard"].forward_table
+for a in nts:
+ for b in nts:
+ for c in nts:
+ codon = "".join((a,b,c))
+ try:
+ aa = codon_tab[codon.replace("U", "T")]
+ except KeyError:
+ aa = "*"
+ codons.append(codon)
+ aas.append(aa)
+n = 0
+print "const size_t n_codons = %s;" % len(codons)
+print
+print "const char *codon_list[] = {" ,
+for cdn in codons:
+ if n % 5 == 0:
+ print "\n ",
+ print '"%s", ' % cdn,
+ n += 1
+print
+print "};"
+n = 0
+print
+print "const char aa_list[] = {",
+for aa in aas:
+ if n % 5 == 0:
+ print "\n ",
+ print "'%s', " % aa,
+ n += 1
+print
+print "};"
+print
diff --git a/src/libqes/util/make_codon_map.py b/src/libqes/util/make_codon_map.py
new file mode 100644
index 0000000..d300dd8
--- /dev/null
+++ b/src/libqes/util/make_codon_map.py
@@ -0,0 +1,21 @@
+from Bio.Data import CodonTable
+
+nts = "ACGTU"
+
+codon_tab = CodonTable.generic_by_name["Standard"].forward_table
+print "char\ntranslate_codon(char *codon)\n{"
+for a in nts:
+ print " else if (codon[0] == '%s') {" % a
+ for b in nts:
+ print " else if (codon[1] == '%s') {" % b
+ for c in nts:
+ print " else if (codon[2] == '%s')" % c ,
+ codon = "".join((a,b,c))
+ try:
+ aa = codon_tab[codon]
+ except KeyError:
+ aa = "*"
+ print "return '%s'" % aa
+ print " }"
+ print " }"
+print "}"
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..d396ab4
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,409 @@
+/*
+ * ============================================================================
+ *
+ * Filename: axe_main.c
+ *
+ * Description: Main loop for axe
+ *
+ * Version: 1.0
+ * Created: 11/06/14 13:37:00
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+
+#include "axe.h"
+
+#include <getopt.h>
+
+static void
+print_version(void)
+{
+ fprintf(stderr, "axe Version %s\n", AXE_VERSION);
+}
+
+static void
+print_help(void)
+{
+ fprintf(stderr, "All mandatory short options are mandatory in their\n");
+ fprintf(stderr, "long option form. Likewise, all short options that take\n");
+ fprintf(stderr, "an argument must be given an argument in their long form\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "If a forward read input is given, a forward read output\n");
+ fprintf(stderr, "must be. Likewise for a reverse/interleaved input. If either\n");
+ fprintf(stderr, "forward and/or reverse reads are given, interleaved input\n");
+ fprintf(stderr, "cannot be. However, one can input interleaved paired reads\n");
+ fprintf(stderr, "and output seperate forwards and reverse reads, and vice versa.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "The barcode file is a tab-seperated tabular file with an\n");
+ fprintf(stderr, "optional header, and has two alternative formats. The standard\n");
+ fprintf(stderr, "form (see below) is expected unless --combinatorial is given.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "The standard format is:\n");
+ fprintf(stderr, "Barcode\tID\n");
+ fprintf(stderr, "ACTA\tA1\n");
+ fprintf(stderr, "CCTC\tA2\n");
+ fprintf(stderr, "...\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "The combinatorial format is:\n");
+ fprintf(stderr, "Barcode1\tBarcode2\tID\n");
+ fprintf(stderr, "ACTA\tACGC\tA1\n");
+ fprintf(stderr, "CCTC\tTCTA\tA2\n");
+ fprintf(stderr, "...\n");
+ fprintf(stderr, "\n");
+}
+
+static void
+print_usage(void)
+{
+ print_version();
+ fprintf(stderr, "\nUSAGE:\n");
+ fprintf(stderr, "axe [-mzc2pt] -b (-f [-r] | -i) (-F [-R] | -I)\n");
+ fprintf(stderr, "axe -h\n");
+ fprintf(stderr, "axe -v\n\n");
+ fprintf(stderr, "OPTIONS:\n");
+ fprintf(stderr, " -m, --mismatch\tMaximum hamming distance mismatch. [int, default 1]\n");
+ fprintf(stderr, " -z, --ziplevel\tGzip compression level, or 0 for plain text [int, default 0]\n");
+ fprintf(stderr, " -c, --combinatorial\tUse combinatorial barcode matching. [flag, default OFF]\n");
+ fprintf(stderr, " -p, --permissive\tDon't error on barcode mismatch confict, matching only\n");
+ fprintf(stderr, " \texactly for conficting barcodes. [flag, default OFF]\n");
+ fprintf(stderr, " -2, --trim-r2\tTrim barcode from R2 read as well as R1. [flag, default OFF]\n");
+ fprintf(stderr, " -b, --barcodes\tBarcode file. See --help for example. [file]\n");
+ fprintf(stderr, " -f, --fwd-in\tInput forward read. [file]\n");
+ fprintf(stderr, " -F, --fwd-out\tOutput forward read prefix. [file]\n");
+ fprintf(stderr, " -r, --rev-in\tInput reverse read. [file]\n");
+ fprintf(stderr, " -R, --rev-out\tOutput reverse read prefix. [file]\n");
+ fprintf(stderr, " -i, --ilfq-in\tInput interleaved paired reads. [file]\n");
+ fprintf(stderr, " -I, --ilfq-out\tOutput interleaved paired reads prefix. [file]\n");
+ fprintf(stderr, " -t, --table-file\tOutput a summary table of demultiplexing statistics to file. [file]\n");
+ fprintf(stderr, " -h, --help\t\tPrint this usage plus additional help.\n");
+ fprintf(stderr, " -V, --version\tPrint version string.\n");
+ fprintf(stderr, " -v, --verbose\tBe more verbose. Additive, -vv is more vebose than -v.\n");
+ fprintf(stderr, " -q, --quiet\t\tBe very quiet.\n");
+ fprintf(stderr, "\n");
+}
+
+static const char *axe_opts = "m:z:c2pb:f:F:r:R:i:I:t:hVvqd";
+static const struct option axe_longopts[] = {
+ { "mismatch", optional_argument, NULL, 'm' },
+ { "ziplevel", required_argument, NULL, 'z' },
+ { "combinatorial", no_argument, NULL, 'c' },
+ { "trim-r2", no_argument, NULL, '2' },
+ { "permissive", no_argument, NULL, 'p' },
+ { "barcodes", required_argument, NULL, 'b' },
+ { "fwd-in", required_argument, NULL, 'f' },
+ { "fwd-out", required_argument, NULL, 'F' },
+ { "rev-in", required_argument, NULL, 'r' },
+ { "rev-out", required_argument, NULL, 'R' },
+ { "ilfq-in", required_argument, NULL, 'i' },
+ { "ilfq-out", required_argument, NULL, 'I' },
+ { "table-file", required_argument, NULL, 't' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "debug", no_argument, NULL, 'd' },
+ { NULL, 0, NULL, 0 }
+};
+
+static int
+parse_args(struct axe_config *config, int argc, char * const *argv)
+{
+ int c = 0;
+ int optind = 0;
+
+ if (argc < 2 ) {
+ return 1;
+ }
+ if (!axe_config_ok(config) || argc < 1 || argv == NULL) {
+ goto error;
+ }
+ /* Set some sane defaults */
+ /* Most things will default to 0 as we `calloc` the config struct, so we
+ * don't need to explicity set them. */
+ config->mismatches = 1;
+ config->verbosity = 0;
+ config->out_compress_level = 0;
+ /* Parse argv using getopt */
+ while ((c = getopt_long(argc, argv, axe_opts, axe_longopts, &optind)) > 0){
+ switch (c) {
+ case 'm':
+ config->mismatches = atol(optarg);
+ break;
+ case 'z':
+ config->out_compress_level = atoi(optarg);
+ break;
+ case 'c':
+ config->match_combo |= 1;
+ break;
+ case 'p':
+ config->permissive |= 1;
+ break;
+ case '2':
+ config->trim_rev |= 1;
+ break;
+ case 'b':
+ config->barcode_file = strdup(optarg);
+ break;
+ case 'f':
+ if (config->in_mode == READS_INTERLEAVED) {
+ goto error;
+ break;
+ }
+ config->infiles[0] = strdup(optarg);
+ if (config->in_mode == READS_UNKNOWN) {
+ config->in_mode = READS_SINGLE;
+ }
+ break;
+ case 'F':
+ config->out_prefixes[0] = strdup(optarg);
+ config->out_mode = READS_SINGLE;
+ break;
+ case 'r':
+ if (config->in_mode == READS_INTERLEAVED) {
+ goto error;
+ break;
+ }
+ config->infiles[1] = strdup(optarg);
+ config->in_mode = READS_PAIRED;
+ break;
+ case 'R':
+ config->out_prefixes[1] = strdup(optarg);
+ config->out_mode = READS_PAIRED;
+ break;
+ case 'i':
+ config->infiles[0] = strdup(optarg);
+ config->in_mode = READS_INTERLEAVED;
+ break;
+ case 'I':
+ config->out_prefixes[0] = strdup(optarg);
+ config->out_mode = READS_INTERLEAVED;
+ break;
+ case 't':
+ config->table_file = strdup(optarg);
+ break;
+ case 'h':
+ goto help;
+ case 'V':
+ goto version;
+ case 'v':
+ config->verbosity += 1;
+ break;
+ case 'q':
+ config->verbosity -= 1;
+ break;
+ case 'd':
+ config->debug = 1;
+ break;
+ case '?':
+ default:
+ /* Getopt long prints its own error msg */
+ goto error;
+ }
+ }
+ /* Check options are sane */
+ if (config->barcode_file == NULL) {
+ fprintf(stderr, "ERROR: Barcode file must be provided\n");
+ goto error;
+ }
+ if (config->mismatches > 4) {
+ fprintf(stderr, "ERROR: Silly mismatch level %" PRIu64 "\n",
+ config->mismatches);
+ goto error;
+ }
+ if (config->in_mode == READS_UNKNOWN) {
+ fprintf(stderr, "ERROR: Input file(s) must be provided\n");
+ goto error;
+ }
+ if (config->infiles[0] == NULL) {
+ switch (config->in_mode) {
+ case READS_SINGLE:
+ fprintf(stderr, "ERROR: Setting forward read input file failed.\n");
+ break;
+ case READS_PAIRED:
+ fprintf(stderr, "ERROR: Forward read file must be provided.\n");
+ break;
+ case READS_INTERLEAVED:
+ fprintf(stderr, "ERROR: Setting interleaved input file failed.\n");
+ break;
+ case READS_UNKNOWN:
+ default:
+ break;
+ }
+ goto error;
+ }
+ if (config->infiles[1] == NULL) {
+ switch (config->in_mode) {
+ case READS_SINGLE:
+ case READS_INTERLEAVED:
+ /* Not an error */
+ break;
+ case READS_PAIRED:
+ fprintf(stderr, "ERROR: Setting revese read input file failed.\n");
+ goto error;
+ break;
+ case READS_UNKNOWN:
+ default:
+ goto error;
+ break;
+ }
+ }
+ if (config->infiles[1] != NULL) {
+ switch (config->in_mode) {
+ case READS_PAIRED:
+ /* Not an error */
+ break;
+ case READS_INTERLEAVED:
+ fprintf(stderr, "ERROR: Revese read input file set in interleaved mode.\n");
+ goto error;
+ break;
+ case READS_SINGLE:
+ fprintf(stderr, "ERROR: Revese read input file set in single-end mode.\n");
+ goto error;
+ break;
+ case READS_UNKNOWN:
+ default:
+ /* Misc weirdness */
+ goto error;
+ break;
+ }
+ }
+ if (config->out_prefixes[0] == NULL) {
+ switch (config->out_mode) {
+ case READS_SINGLE:
+ fprintf(stderr, "ERROR: Setting forward read output prefix failed.\n");
+ break;
+ case READS_PAIRED:
+ fprintf(stderr, "ERROR: Forward read prefix must be provided.\n");
+ break;
+ case READS_INTERLEAVED:
+ fprintf(stderr, "ERROR: Setting interleaved output prefix failed.\n");
+ break;
+ case READS_UNKNOWN:
+ default:
+ break;
+ }
+ goto error;
+ }
+ if (config->out_prefixes[1] == NULL) {
+ switch (config->out_mode) {
+ case READS_SINGLE:
+ case READS_INTERLEAVED:
+ /* Not an error */
+ break;
+ case READS_PAIRED:
+ fprintf(stderr, "ERROR: Setting revese read output prefix failed.\n");
+ goto error;
+ break;
+ case READS_UNKNOWN:
+ default:
+ goto error;
+ break;
+ }
+ }
+ if (config->out_prefixes[1] != NULL) {
+ switch (config->out_mode) {
+ case READS_PAIRED:
+ /* Not an error */
+ break;
+ case READS_INTERLEAVED:
+ fprintf(stderr, "ERROR: Revese read output prefix set in interleaved mode.\n");
+ goto error;
+ break;
+ case READS_SINGLE:
+ case READS_UNKNOWN:
+ default:
+ /* Misc weirdness */
+ goto error;
+ break;
+ }
+ }
+ config->have_cli_opts = 1;
+ format_call_number = 0;
+ qes_logger_init(config->logger, "[axe] ", QES_LOG_DEBUG);
+ qes_logger_add_destination_formatted(config->logger, stderr, QES_LOG_DEBUG,
+ &axe_formatter);
+ return 0;
+error:
+ fprintf(stderr,
+ "Axe failed due to bad CLI flags. Consult the usage below please!\n\n");
+ config->have_cli_opts = 0;
+ return 1;
+help:
+ config->have_cli_opts = 0;
+ return 2;
+version:
+ print_version();
+ axe_config_destroy(config);
+ exit(0);
+}
+
+int
+main (int argc, char * const *argv)
+{
+ int ret = 0;
+ struct axe_config *config = axe_config_create();
+
+ if (config == NULL) {
+ ret = EXIT_FAILURE;
+ goto end;
+ }
+ ret = parse_args(config, argc, argv);
+ if (ret != 0) {
+ print_usage();
+ if (ret == 2) {
+ print_help();
+ }
+ goto end;
+ }
+ ret = axe_read_barcodes(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_read_barcodes returned %i\n", ret);
+ fprintf(stderr, "\tThis indicates that the barcode file is invalid.\n");
+ fprintf(stderr, "\tPlease check that it conforms to the layout described in the help message\n");
+ goto end;
+ }
+ ret = axe_setup_barcode_lookup(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_setup_barcode_lookup returned %i\n",
+ ret);
+ goto end;
+ }
+ ret = axe_make_tries(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_make_tries returned %i\n", ret);
+ goto end;
+ }
+ ret = axe_load_tries(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_load_tries returned %i\n", ret);
+ goto end;
+ }
+ ret = axe_make_outputs(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_make_outputs returned %i\n", ret);
+ goto end;
+ }
+ ret = axe_process_file(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_process_file returned %i\n", ret);
+ goto end;
+ }
+ ret = axe_print_summary(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_print_summary returned %i\n", ret);
+ goto end;
+ }
+ ret = axe_write_table(config);
+ if (ret != 0) {
+ fprintf(stderr, "[main] ERROR: axe_write_table returned %i\n", ret);
+ goto end;
+ }
+end:
+ axe_config_destroy(config);
+ return ret;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..700ff01
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,91 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/tinytest)
+
+ADD_EXECUTABLE(test_axe test.c ${CMAKE_CURRENT_SOURCE_DIR}/tinytest/tinytest.c test_libaxe.c)
+TARGET_LINK_LIBRARIES(test_axe ${AXE_DEPENDS_LIBRARIES} axelib)
+
+# Copy test files over to bin dir & make output
+ADD_CUSTOM_TARGET(setup_tests ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_SOURCE_DIR}/data
+ ${CMAKE_BINARY_DIR}/data
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/axe_integration.py
+ ${CMAKE_BINARY_DIR}/bin
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/out)
+ADD_DEPENDENCIES(test_axe setup_tests)
+
+ADD_TEST(NAME "UnitTests" COMMAND test_axe)
+SET(COVERAGE_CMD test_axe)
+SET(COVERAGE_OUT "${CMAKE_BINARY_DIR}/coverage_html")
+
+ADD_TEST(NAME "IntegrationTests" COMMAND python
+ ${CMAKE_BINARY_DIR}/bin/axe_integration.py
+ ${CMAKE_BINARY_DIR})
+
+IF (CMAKE_BUILD_TYPE STREQUAL "Coverage")
+ FIND_PROGRAM( GCOV_PATH gcov )
+ FIND_PROGRAM( LCOV_PATH lcov )
+ FIND_PROGRAM( GENHTML_PATH genhtml )
+ FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
+
+ SET(CMAKE_C_FLAGS_COVERAGE
+ "${CMAKE_C_FLAGS_DEBUG} -g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C compiler during coverage builds."
+ FORCE)
+ SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE)
+ SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE)
+ MARK_AS_ADVANCED(
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
+
+ IF(NOT GCOV_PATH)
+ MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
+ ENDIF() # NOT GCOV_PATH
+ IF(NOT LCOV_PATH)
+ MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
+ ENDIF() # NOT LCOV_PATH
+ IF(NOT GENHTML_PATH)
+ MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
+ ENDIF() # NOT GENHTML_PATH
+ IF(NOT CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_COMPILER_IS_GNUCXX)
+ # Clang version 3.0.0 and greater now supports gcov as well.
+ MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
+ IF(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+ ENDIF()
+ ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX
+
+ # Setup target
+ ADD_CUSTOM_TARGET(coverage
+ # Cleanup lcov
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory ${CMAKE_BINARY_DIR}/src --zerocounters
+
+ # Run tests
+ COMMAND ${COVERAGE_CMD}
+
+ # Capturing lcov counters and generating report
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory ${CMAKE_BINARY_DIR}/src --capture --output-file ${COVERAGE_OUT}.info
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --output-file ${COVERAGE_OUT}.info --remove ${COVERAGE_OUT}.info src/kmlib/*
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --output-file ${COVERAGE_OUT}.info --remove ${COVERAGE_OUT}.info src/datrie/*
+ COMMAND ${GENHTML_PATH} --branch-coverage -o ${COVERAGE_OUT} ${COVERAGE_OUT}.info
+ COMMAND ${CMAKE_COMMAND} -E remove ${COVERAGE_OUT}.info
+
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
+ )
+
+ # Show info where to find the report
+ ADD_CUSTOM_COMMAND(TARGET coverage POST_BUILD
+ COMMAND ;
+ COMMENT "Open ${COVERAGE_OUT}/index.html in your browser to view the coverage report."
+ )
+
+ENDIF() # build type coverage
diff --git a/tests/axe_integration.py b/tests/axe_integration.py
new file mode 100644
index 0000000..8063175
--- /dev/null
+++ b/tests/axe_integration.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+from __future__ import print_function
+import logging
+import os
+from os import path
+import re
+import shutil
+import subprocess as sp
+import sys
+import unittest
+
+
+if len(sys.argv) < 2:
+ print("USAGE: axe_integration.py $CMAKE_BINARY_DIR")
+ exit(-1)
+
+CMAKE_BINARY_DIR = sys.argv.pop(1)
+
+
+class AxeTest(unittest.TestCase):
+ maxDiff= None
+
+ def __init__(self, methodName='runTest'):
+ super(AxeTest, self).__init__(methodName)
+ self.data = path.join(CMAKE_BINARY_DIR, "data")
+ self.out = path.join(CMAKE_BINARY_DIR, "out", "integration")
+ self.axe = path.join(CMAKE_BINARY_DIR, "bin", "axe")
+ self.log = logging.getLogger("AxeTest")
+ if not path.exists(self.data) or not path.exists(self.axe):
+ print("Please run axe_integration.py after compiling axe")
+ exit(-1)
+
+ def setUp(self):
+ if not path.exists(self.out):
+ os.makedirs(self.out)
+
+ def run_and_check_stdout(self, command):
+ self.log.debug(" ".join(command))
+ try:
+ output = sp.check_output(command, stderr=sp.STDOUT)
+ except sp.CalledProcessError as err:
+ self.log.info(err.output)
+ return False
+ return True
+
+ def get_md5_dict(self):
+ dct = {}
+ for root, dirs, files in os.walk(self.out):
+ for fle in files:
+ md5 = sp.check_output(["md5sum", path.join(root, fle)])
+ md5, fle = md5.strip().split()
+ dct[path.basename(fle)] = md5
+ return dct
+
+ def tearDown(self):
+ if path.exists(self.out):
+ shutil.rmtree(self.out)
+
+
+class TestBadUsage(AxeTest):
+ def __init__(self, methodName='runTest'):
+ super(TestBadUsage, self).__init__(methodName)
+
+ def test_bad_command(self):
+ command = [self.axe, "-f"]
+ self.assertFalse(self.run_and_check_stdout(command))
+ self.assertDictEqual({}, self.get_md5_dict())
+
+
+class TestPareSE(AxeTest):
+ def __init__(self, methodName='runTest'):
+ super(TestPareSE, self).__init__(methodName)
+ self.infq = path.join(self.data, "pare.fq.gz")
+ self.barcodes = path.join(self.data, "pare.barcodes")
+ self.outfq = path.join(self.out, "pare_se")
+ self.nobcdfq = path.join(self.out, "pare_se_unknown_R1.fastq")
+
+ def test_pare_se(self):
+ command = [self.axe,
+ "-f", self.infq,
+ "-F", self.outfq,
+ '-b', self.barcodes,
+ ]
+ self.assertTrue(self.run_and_check_stdout(command))
+ files = {
+ 'pare_se_1_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'pare_se_2_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'pare_se_3_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'pare_se_4_R1.fastq': '8e5eef3323e597b209f79dc9fcd74c9a',
+ 'pare_se_5_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'pare_se_6_R1.fastq': '7228a165f353920328360dedc3a41205',
+ 'pare_se_7_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'pare_se_8_R1.fastq': 'b349d3276ba7c7515d0093b1a49b3959',
+ 'pare_se_9_R1.fastq': '74b4763271aefcc135425b06730874ba',
+ 'pare_se_unknown_R1.fastq': 'd450569dd8fd4bdddffbfaeec4980273',
+ }
+ self.assertDictEqual(files, self.get_md5_dict())
+
+ def test_pare_se_zip(self):
+ command = [self.axe,
+ "-f", self.infq,
+ "-F", self.outfq,
+ '-b', self.barcodes,
+ '-z', '9',
+ ]
+ files = {
+ 'pare_se_1_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'pare_se_2_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'pare_se_3_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'pare_se_4_R1.fastq.gz': '96d21b860a0fc70641ea43d350433d11',
+ 'pare_se_5_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'pare_se_6_R1.fastq.gz': 'd6044c04f79c358e4a1d443f8828df18',
+ 'pare_se_7_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'pare_se_8_R1.fastq.gz': 'da77b8e95827d362a1702ce4fe75c7a9',
+ 'pare_se_9_R1.fastq.gz': '9c160b0daa0c73e5ef0994206774a5a0',
+ 'pare_se_unknown_R1.fastq.gz': 'afd5737935814d756e89c365d2d61c7b',
+ }
+ self.assertTrue(self.run_and_check_stdout(command))
+ self.assertDictEqual(files, self.get_md5_dict())
+
+class TestFakeSE(AxeTest):
+ files = {
+ 'fake_se_1_R1.fastq': '836eaf06938d4a41122f284ed487a9c7',
+ 'fake_se_2_R1.fastq': '836eaf06938d4a41122f284ed487a9c7',
+ 'fake_se_unknown_R1.fastq': '836eaf06938d4a41122f284ed487a9c7',
+ }
+ zfiles = {
+ 'fake_se_1_R1.fastq.gz': '3e07353d24a3ecd315067250a6be6047',
+ 'fake_se_2_R1.fastq.gz': '3e07353d24a3ecd315067250a6be6047',
+ 'fake_se_unknown_R1.fastq.gz': '3e07353d24a3ecd315067250a6be6047',
+ }
+
+ def __init__(self, methodName='runTest'):
+ super(TestFakeSE, self).__init__(methodName)
+ self.barcodes = path.join(self.data, "fake.barcodes")
+ self.outfq = path.join(self.out, "fake_se")
+ self.nobcdfq = path.join(self.out, "fake_se_unknown_R1.fastq")
+
+ def _do_test(self, mm_level):
+ infq = path.join(self.data, "fake_{}mm_R1.fq.gz".format(mm_level))
+ command = [self.axe,
+ "-f", infq,
+ "-F", self.outfq,
+ '-b', self.barcodes,
+ ]
+ self.assertTrue(self.run_and_check_stdout(command))
+
+ def _do_test_zip(self, mm_level):
+ infq = path.join(self.data, "fake_{}mm_R1.fq.gz".format(mm_level))
+ command = [self.axe,
+ "-f", infq,
+ "-F", self.outfq,
+ '-b', self.barcodes,
+ '-z', '9',
+ ]
+ self.assertTrue(self.run_and_check_stdout(command))
+
+ def test_fake_se_0mm(self):
+ self._do_test(0)
+ self.assertDictEqual(self.files, self.get_md5_dict())
+
+ def test_fake_se_0mm_zip(self):
+ self._do_test_zip(0)
+ self.assertDictEqual(self.zfiles, self.get_md5_dict())
+
+ def test_fake_se_1mm(self):
+ self._do_test(1)
+ self.assertDictEqual(self.files, self.get_md5_dict())
+
+ def test_fake_se_1mm_zip(self):
+ self._do_test_zip(1)
+ self.assertDictEqual(self.zfiles, self.get_md5_dict())
+
+ def test_fake_se_2mm(self):
+ self._do_test(2)
+ files = {
+ 'fake_se_1_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'fake_se_2_R1.fastq': 'd41d8cd98f00b204e9800998ecf8427e',
+ 'fake_se_unknown_R1.fastq': 'a6de105b6c5abbc2d0d16440333adc64',
+ }
+ self.assertDictEqual(files, self.get_md5_dict())
+
+ def test_fake_se_2mm_zip(self):
+ self._do_test_zip(2)
+ zfiles = {
+ 'fake_se_1_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'fake_se_2_R1.fastq.gz': '4a4dd3598707603b3f76a2378a4504aa',
+ 'fake_se_unknown_R1.fastq.gz': 'ee6979b139dbd898f058fd7649f87da2',
+ }
+ self.assertDictEqual(zfiles, self.get_md5_dict())
+
+
+if __name__ == '__main__':
+ log = logging.getLogger("AxeTest")
+ fmt = logging.Formatter('%(message)s')
+ cons = logging.StreamHandler()
+ cons.setLevel(logging.DEBUG)
+ cons.setFormatter(fmt)
+ log.addHandler(cons)
+ log.setLevel(logging.DEBUG)
+ unittest.main()
diff --git a/tests/data/fake.barcodes b/tests/data/fake.barcodes
new file mode 100644
index 0000000..b513b0e
--- /dev/null
+++ b/tests/data/fake.barcodes
@@ -0,0 +1,3 @@
+Barcode ID
+ATCACG 1
+CGATGT 2
diff --git a/tests/data/fake_0mm_R1.fq.gz b/tests/data/fake_0mm_R1.fq.gz
new file mode 100644
index 0000000..0ab2656
Binary files /dev/null and b/tests/data/fake_0mm_R1.fq.gz differ
diff --git a/tests/data/fake_1mm_R1.fq.gz b/tests/data/fake_1mm_R1.fq.gz
new file mode 100644
index 0000000..5fcf423
Binary files /dev/null and b/tests/data/fake_1mm_R1.fq.gz differ
diff --git a/tests/data/fake_2mm_R1.fq.gz b/tests/data/fake_2mm_R1.fq.gz
new file mode 100644
index 0000000..d423676
Binary files /dev/null and b/tests/data/fake_2mm_R1.fq.gz differ
diff --git a/tests/data/gbs.barcodes b/tests/data/gbs.barcodes
new file mode 100644
index 0000000..14f9746
--- /dev/null
+++ b/tests/data/gbs.barcodes
@@ -0,0 +1,97 @@
+Barcode1 Barcode2 ID
+CTCGTGCAG CGAGTGCAG A1
+TGCATGCAG TGCATGCAG A2
+ACTATGCAG TAGTTGCAG A3
+CAGATGCAG TCTGTGCAG A4
+AACTTGCAG AGTTTGCAG A5
+GCGTTGCAG ACGCTGCAG A6
+CGATTGCAG ATCGTGCAG A7
+GTAATGCAG TTACTGCAG A8
+AGGGTGCAG CCCTTGCAG A9
+GATGTGCAG CATCTGCAG A10
+TCAGTGCAG CTGATGCAG A11
+TGCGATGCAG TCGCATGCAG A12
+CGCTTTGCAG AAGCGTGCAG B1
+TCACGTGCAG CGTGATGCAG B2
+CTAGGTGCAG CCTAGTGCAG B3
+ACAAATGCAG TTTGTTGCAG B4
+TTCTGTGCAG CAGAATGCAG B5
+AGCCGTGCAG CGGCTTGCAG B6
+GTATTTGCAG AATACTGCAG B7
+CTGTATGCAG TACAGTGCAG B8
+ACCGTTGCAG ACGGTTGCAG B9
+GCTTATGCAG TAAGCTGCAG B10
+GGTGTTGCAG ACACCTGCAG B11
+AGGATTGCAG ATCCTTGCAG B12
+ATTGATGCAG TCAATTGCAG C1
+CATCTTGCAG AGATGTGCAG C2
+CCTAGTGCAG CTAGGTGCAG C3
+GAGGATGCAG TCCTCTGCAG C4
+GGAAGTGCAG CTTCCTGCAG C5
+GTCAATGCAG TTGACTGCAG C6
+TAATATGCAG TATTATGCAG C7
+TACATTGCAG ATGTATGCAG C8
+TCGTTTGCAG AACGATGCAG C9
+GGTTGTTGCAG ACAACCTGCAG C10
+CCAGCTTGCAG AGCTGGTGCAG C11
+TTCAGATGCAG TCTGAATGCAG C12
+TAGGAATGCAG TTCCTATGCAG D1
+GCTCTATGCAG TAGAGCTGCAG D2
+CCACAATGCAG TTGTGGTGCAG D3
+CTTCCATGCAG TGGAAGTGCAG D4
+GAGATATGCAG TATCTCTGCAG D5
+ATGCCTTGCAG AGGCATTGCAG D6
+AGTGGATGCAG TCCACTTGCAG D7
+ACCTAATGCAG TTAGGTTGCAG D8
+ATATGTTGCAG ACATATTGCAG D9
+ATCGTATGCAG TACGATTGCAG D10
+CATCGTTGCAG ACGATGTGCAG D11
+CGCGGTTGCAG ACCGCGTGCAG D12
+CTATTATGCAG TAATAGTGCAG E1
+GCCAGTTGCAG ACTGGCTGCAG E2
+GGAAGATGCAG TCTTCCTGCAG E3
+GTACTTTGCAG AAGTACTGCAG E4
+GTTGAATGCAG TTCAACTGCAG E5
+TAACGATGCAG TCGTTATGCAG E6
+TGGCTATGCAG TAGCCATGCAG E7
+TATTTTTTGCAG AAAAATATGCAG E8
+CTTGCTTTGCAG AAGCAAGTGCAG E9
+ATGAAAGTGCAG CTTTCATTGCAG E10
+AAAAGTTTGCAG AACTTTTTGCAG E11
+GAATTCATGCAG TGAATTCTGCAG E12
+GAACTTGTGCAG CAAGTTCTGCAG F1
+GGACCTATGCAG TAGGTCCTGCAG F2
+GTCGATTTGCAG AATCGACTGCAG F3
+AACGCCTTGCAG AGGCGTTTGCAG F4
+AATATGGTGCAG CCATATTTGCAG F5
+ACGTGTTTGCAG AACACGTTGCAG F6
+ATTAATTTGCAG AATTAATTGCAG F7
+ATTGGATTGCAG ATCCAATTGCAG F8
+CATAAGTTGCAG ACTTATGTGCAG F9
+CGCTGATTGCAG ATCAGCGTGCAG F10
+CGGTAGATGCAG TCTACCGTGCAG F11
+CTACGGATGCAG TCCGTAGTGCAG F12
+GCGGAATTGCAG ATTCCGCTGCAG G1
+TAGCGGATGCAG TCCGCTATGCAG G2
+TCGAAGATGCAG TCTTCGATGCAG G3
+TCTGTGATGCAG TCACAGATGCAG G4
+TGCTGGATGCAG TCCAGCATGCAG G5
+ACGACTAGTGCAG CTAGTCGTTGCAG G6
+TAGCATGGTGCAG CCATGCTATGCAG G7
+TAGGCCATTGCAG ATGGCCTATGCAG G8
+TGCAAGGATGCAG TCCTTGCATGCAG G9
+TGGTACGTTGCAG ACGTACCATGCAG G10
+TCTCAGTGTGCAG CACTGAGATGCAG G11
+CCGGATATTGCAG ATATCCGGTGCAG G12
+CGCCTTATTGCAG ATAAGGCGTGCAG H1
+AACCGAGATGCAG TCTCGGTTTGCAG H2
+ACAGGGAATGCAG TTCCCTGTTGCAG H3
+ACGTGGTATGCAG TACCACGTTGCAG H4
+CCATGGGTTGCAG ACCCATGGTGCAG H5
+CGCGGAGATGCAG TCTCCGCGTGCAG H6
+CGTGTGGTTGCAG ACCACACGTGCAG H7
+GCTGTGGATGCAG TCCACAGCTGCAG H8
+GGATTGGTTGCAG ACCAATCCTGCAG H9
+GTGAGGGTTGCAG ACCCTCACTGCAG H10
+TATCGGGATGCAG TCCCGATATGCAG H11
+TTCCTGGATGCAG TCCAGGAATGCAG H12
diff --git a/tests/data/gbs_R1.fastq.gz b/tests/data/gbs_R1.fastq.gz
new file mode 100644
index 0000000..3fe2474
Binary files /dev/null and b/tests/data/gbs_R1.fastq.gz differ
diff --git a/tests/data/gbs_R2.fastq.gz b/tests/data/gbs_R2.fastq.gz
new file mode 100644
index 0000000..15b75b3
Binary files /dev/null and b/tests/data/gbs_R2.fastq.gz differ
diff --git a/tests/data/gbs_se.barcodes b/tests/data/gbs_se.barcodes
new file mode 100644
index 0000000..dc21710
--- /dev/null
+++ b/tests/data/gbs_se.barcodes
@@ -0,0 +1,97 @@
+Barcode1 ID
+CTCGTGCAG A1
+TGCATGCAG A2
+ACTATGCAG A3
+CAGATGCAG A4
+AACTTGCAG A5
+GCGTTGCAG A6
+CGATTGCAG A7
+GTAATGCAG A8
+AGGGTGCAG A9
+GATGTGCAG A10
+TCAGTGCAG A11
+TGCGATGCAG A12
+CGCTTTGCAG B1
+TCACGTGCAG B2
+CTAGGTGCAG B3
+ACAAATGCAG B4
+TTCTGTGCAG B5
+AGCCGTGCAG B6
+GTATTTGCAG B7
+CTGTATGCAG B8
+ACCGTTGCAG B9
+GCTTATGCAG B10
+GGTGTTGCAG B11
+AGGATTGCAG B12
+ATTGATGCAG C1
+CATCTTGCAG C2
+CCTAGTGCAG C3
+GAGGATGCAG C4
+GGAAGTGCAG C5
+GTCAATGCAG C6
+TAATATGCAG C7
+TACATTGCAG C8
+TCGTTTGCAG C9
+GGTTGTTGCAG C10
+CCAGCTTGCAG C11
+TTCAGATGCAG C12
+TAGGAATGCAG D1
+GCTCTATGCAG D2
+CCACAATGCAG D3
+CTTCCATGCAG D4
+GAGATATGCAG D5
+ATGCCTTGCAG D6
+AGTGGATGCAG D7
+ACCTAATGCAG D8
+ATATGTTGCAG D9
+ATCGTATGCAG D10
+CATCGTTGCAG D11
+CGCGGTTGCAG D12
+CTATTATGCAG E1
+GCCAGTTGCAG E2
+GGAAGATGCAG E3
+GTACTTTGCAG E4
+GTTGAATGCAG E5
+TAACGATGCAG E6
+TGGCTATGCAG E7
+TATTTTTTGCAG E8
+CTTGCTTTGCAG E9
+ATGAAAGTGCAG E10
+AAAAGTTTGCAG E11
+GAATTCATGCAG E12
+GAACTTGTGCAG F1
+GGACCTATGCAG F2
+GTCGATTTGCAG F3
+AACGCCTTGCAG F4
+AATATGGTGCAG F5
+ACGTGTTTGCAG F6
+ATTAATTTGCAG F7
+ATTGGATTGCAG F8
+CATAAGTTGCAG F9
+CGCTGATTGCAG F10
+CGGTAGATGCAG F11
+CTACGGATGCAG F12
+GCGGAATTGCAG G1
+TAGCGGATGCAG G2
+TCGAAGATGCAG G3
+TCTGTGATGCAG G4
+TGCTGGATGCAG G5
+ACGACTAGTGCAG G6
+TAGCATGGTGCAG G7
+TAGGCCATTGCAG G8
+TGCAAGGATGCAG G9
+TGGTACGTTGCAG G10
+TCTCAGTGTGCAG G11
+CCGGATATTGCAG G12
+CGCCTTATTGCAG H1
+AACCGAGATGCAG H2
+ACAGGGAATGCAG H3
+ACGTGGTATGCAG H4
+CCATGGGTTGCAG H5
+CGCGGAGATGCAG H6
+CGTGTGGTTGCAG H7
+GCTGTGGATGCAG H8
+GGATTGGTTGCAG H9
+GTGAGGGTTGCAG H10
+TATCGGGATGCAG H11
+TTCCTGGATGCAG H12
diff --git a/tests/data/pare.barcodes b/tests/data/pare.barcodes
new file mode 100644
index 0000000..b90b4e1
--- /dev/null
+++ b/tests/data/pare.barcodes
@@ -0,0 +1,10 @@
+Barcode ID
+ATCACG 1
+CGATGT 2
+TTAGGC 3
+TGACCA 4
+ACAGTG 5
+GCCAAT 6
+CAGATC 7
+ACTTGA 8
+GATCAG 9
diff --git a/tests/data/pare.fq.gz b/tests/data/pare.fq.gz
new file mode 100644
index 0000000..454e6b3
Binary files /dev/null and b/tests/data/pare.fq.gz differ
diff --git a/tests/data/pare_full.fq.gz b/tests/data/pare_full.fq.gz
new file mode 100644
index 0000000..93a1a22
Binary files /dev/null and b/tests/data/pare_full.fq.gz differ
diff --git a/tests/test.c b/tests/test.c
new file mode 100644
index 0000000..48b94a5
--- /dev/null
+++ b/tests/test.c
@@ -0,0 +1,60 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test.c
+ *
+ * Description: Tests for axe
+ *
+ * Version: 1.0
+ * Created: 20/06/14 17:14:55
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+#include "tests.h"
+#include <assert.h>
+
+
+struct testgroup_t axe_tests[] = {
+ {"libaxe/", core_tests},
+ END_OF_GROUPS
+};
+
+
+/*
+ * === FUNCTION =============================================================
+ * Name: main
+ * Description: Run all tests
+ * ============================================================================
+ */
+
+int
+main (int argc, const char *argv[])
+{
+ int res;
+ int our_argc = argc;
+ const char **our_argv = argv;
+ char *data_prefix;
+
+ data_prefix = NULL;
+ if (argc>1) {
+ data_prefix = strdup(argv[1]);
+ our_argc -= 1;
+ our_argv += 1;
+ } else {
+ data_prefix = strdup(".");
+ }
+ assert(data_prefix != NULL);
+ if (access(data_prefix, W_OK | X_OK | R_OK) != 0) {
+ fprintf(stderr, "Could not access data prefix dir '%s'\n", data_prefix);
+ free(data_prefix);
+ exit(EXIT_FAILURE);
+ }
+ res = tinytest_main(our_argc, our_argv, axe_tests);
+ free(data_prefix);
+ return res;
+}
diff --git a/tests/test_libaxe.c b/tests/test_libaxe.c
new file mode 100644
index 0000000..d1448e1
--- /dev/null
+++ b/tests/test_libaxe.c
@@ -0,0 +1,95 @@
+/*
+ * ============================================================================
+ *
+ * Filename: test_libaxe.c
+ *
+ * Description: Tests of core functionality
+ *
+ * Version: 1.0
+ * Created: 22/06/14 13:23:46
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#include "tests.h"
+
+static void
+test_product (void *ptr)
+{
+ const uint64_t len = 4;
+ const uint64_t elem = 2;
+ uintptr_t choices[] = {0,0};
+ /* Truth from python's itertools.product */
+ uintptr_t truth[][2] = {
+ {0, 0}, {0, 1}, {0, 2}, {0, 3},
+ {1, 0}, {1, 1}, {1, 2}, {1, 3},
+ {2, 0}, {2, 1}, {2, 2}, {2, 3},
+ {3, 0}, {3, 1}, {3, 2}, {3, 3}, };
+ int ret = 0;
+ int count = 0;
+ size_t iii = 0;
+
+ (void)ptr;
+ while ((ret = product(len, elem, choices, !ret)) == 1) {
+
+ for (iii = 0; iii < elem; iii++) {
+ tt_int_op(choices[iii], ==, truth[count][iii]);
+ }
+ count++;
+ }
+ tt_int_op(ret, ==, 0);
+ tt_int_op(count, ==, 16);
+end:
+ ;
+}
+
+static void
+test_hamming_mutate (void *ptr)
+{
+ char **mutated = NULL;
+ size_t count = 0;
+ size_t iii = 0;
+ const char *str = "AAAA";
+ const char *truth[] = {
+ "AAAA", "ACAA", "AGAA", "ATAA", "CAAA", "CCAA", "CGAA", "CTAA", "GAAA",
+ "GCAA", "GGAA", "GTAA", "TAAA", "TCAA", "TGAA", "TTAA", "AAAA", "AACA",
+ "AAGA", "AATA", "CAAA", "CACA", "CAGA", "CATA", "GAAA", "GACA", "GAGA",
+ "GATA", "TAAA", "TACA", "TAGA", "TATA", "AAAA", "AAAC", "AAAG", "AAAT",
+ "CAAA", "CAAC", "CAAG", "CAAT", "GAAA", "GAAC", "GAAG", "GAAT", "TAAA",
+ "TAAC", "TAAG", "TAAT", "AAAA", "AACA", "AAGA", "AATA", "ACAA", "ACCA",
+ "ACGA", "ACTA", "AGAA", "AGCA", "AGGA", "AGTA", "ATAA", "ATCA", "ATGA",
+ "ATTA", "AAAA", "AAAC", "AAAG", "AAAT", "ACAA", "ACAC", "ACAG", "ACAT",
+ "AGAA", "AGAC", "AGAG", "AGAT", "ATAA", "ATAC", "ATAG", "ATAT", "AAAA",
+ "AAAC", "AAAG", "AAAT", "AACA", "AACC", "AACG", "AACT", "AAGA", "AAGC",
+ "AAGG", "AAGT", "AATA", "AATC", "AATG", "AATT", };
+
+ (void) ptr;
+ mutated = hamming_mutate_dna(&count, str, strlen(str), 2, 1);
+ tt_ptr_op(mutated, !=, NULL);
+ tt_int_op(count, ==, 96);
+ for (iii = 0; iii < count; iii++) {
+ tt_ptr_op(mutated[iii], !=, NULL);
+ tt_str_op(mutated[iii], ==, truth[iii]);
+ }
+
+end:
+ if (mutated != NULL) {
+ for (iii = 0; iii < count; iii++) {
+ if (mutated[iii] != NULL) {
+ free(mutated[iii]);
+ }
+ }
+ free(mutated);
+ }
+}
+
+struct testcase_t core_tests[] = {
+ { "product", test_product, 0, NULL, NULL},
+ { "hamming_mutate", test_hamming_mutate, 0, NULL, NULL},
+ END_OF_TESTCASES
+};
diff --git a/tests/tests.h b/tests/tests.h
new file mode 100644
index 0000000..422aa47
--- /dev/null
+++ b/tests/tests.h
@@ -0,0 +1,47 @@
+/*
+ * ============================================================================
+ *
+ * Filename: tests.h
+ *
+ * Description: All tests for axe, and all common includes.
+ *
+ * Version: 1.0
+ * Created: 20/06/14 17:16:52
+ * Revision: none
+ * License: GPLv3+
+ * Compiler: gcc, clang
+ *
+ * Author: Kevin Murray, spam at kdmurray.id.au
+ *
+ * ============================================================================
+ */
+
+#ifndef AXE_TESTS_H
+#define AXE_TESTS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* TinyTest */
+#include "tinytest/tinytest.h"
+#include "tinytest/tinytest_macros.h"
+
+#include <qes.h>
+
+#include "axe.h"
+
+
+/* Core tests */
+extern struct testcase_t core_tests[];
+#endif /* ifndef AXE_TESTS_H */
diff --git a/utils/make-tarball.sh b/utils/make-tarball.sh
new file mode 100644
index 0000000..a23f4a9
--- /dev/null
+++ b/utils/make-tarball.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+
+version=$1
+
+git tag -v "$version"
+if [ $? -ne 0 ]
+then
+ echo "Invalid tag: $version"
+ exit 1
+fi
+
+set -xe
+
+rm -f ../axe_${version}.orig.tar*
+git archive -o ../axe_${version}.orig.tar $version
+tar -rvf ../axe_${version}.orig.tar --owner=0 --group=0 src/libqes/
+xz ../axe_${version}.orig.tar
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/axe-demultiplexer.git
More information about the debian-med-commit
mailing list