[med-svn] [unanimity] 01/04: Imported Upstream version 2.0.4+dfsg
Afif Elghraoui
afif at moszumanska.debian.org
Mon Dec 19 06:16:08 UTC 2016
This is an automated email from the git hooks/post-receive script.
afif pushed a commit to branch master
in repository unanimity.
commit 61ac353ccc8e1746a722adb43003e693fb1a6fc5
Author: Afif Elghraoui <afif at debian.org>
Date: Wed Dec 14 21:46:08 2016 -0800
Imported Upstream version 2.0.4+dfsg
---
.gitmodules | 20 +-
CHANGELOG.md | 12 +
CMakeLists.txt | 2 +-
README.md | 4 +-
build.sh | 103 +++
cmake/uny-dependencies.cmake | 14 +-
.../ZScoreMath.rst | 267 ++++++
.../img/consensus-modalities.pdf | Bin 0 -> 184757 bytes
.../img/consensus-modalities.png | Bin 0 -> 270181 bytes
.../img/hmms.pdf | Bin 0 -> 194111 bytes
.../img/hmms.png | Bin 0 -> 373013 bytes
.../index.rst | 281 +++++-
.../pacbioHMM.svg.png | Bin 0 -> 61715 bytes
doc/INSTALL.md | 13 +-
include/pacbio/ccs/Consensus.h | 87 +-
.../pacbio/ccs/ConsensusSettings.h | 64 +-
include/pacbio/consensus/AbstractIntegrator.h | 24 +-
include/pacbio/consensus/AbstractMatrix.h | 19 +-
include/pacbio/consensus/Evaluator.h | 68 +-
.../pacbio/consensus/MatrixViewConvention.h | 29 +-
include/pacbio/consensus/MonoMolecularIntegrator.h | 15 +-
.../pacbio/consensus/MultiMolecularIntegrator.h | 11 +-
include/pacbio/consensus/Mutation.h | 8 +
include/pacbio/consensus/Polish.h | 10 +
include/pacbio/consensus/Template.h | 2 +-
.../pacbio/data/PlainOption.h | 48 +-
include/pacbio/data/Read.h | 4 +
include/pacbio/denovo/PoaGraph.h | 2 +
include/pacbio/denovo/SparsePoa.h | 2 +
scripts/task_pbccs_ccs | 218 -----
src/AbstractIntegrator.cpp | 2 +-
src/CMakeLists.txt | 4 +-
src/ConsensusSettings.cpp | 300 +++++++
src/Evaluator.cpp | 18 +
src/EvaluatorImpl.cpp | 55 +-
src/EvaluatorImpl.h | 5 +
src/ModelSelection.cpp | 5 +-
src/Read.cpp | 6 +-
src/Recursor.h | 201 +++--
src/Sequence.cpp | 2 +-
src/SparsePoa.cpp | 7 +-
src/Timer.cpp | 2 +-
src/Utility.cpp | 5 +-
src/align/AlignConfig.cpp | 2 +-
src/main/ccs.cpp | 236 ++---
.../Polish.h => src/matrix/BasicDenseMatrix.cpp | 50 +-
src/{EvaluatorImpl.h => matrix/BasicDenseMatrix.h} | 94 +-
src/matrix/ScaledMatrix.h | 14 +
src/matrix/SparseMatrix.h | 23 +-
src/poa/PoaGraph.cpp | 5 +
src/poa/PoaGraphImpl.cpp | 17 +
src/poa/PoaGraphImpl.h | 1 +
swig/Matrix.i | 2 +
swig/Mutation.i | 10 +
swig/State.i | 6 +-
tests/CMakeLists.txt | 1 -
tests/cram/100zmws.t | 25 +-
tests/cram/100zmws_byStrand.t | 113 +--
tests/cram/tiny.t | 2 +-
tests/python/test_tool_contract.py | 2 +-
tests/unit/TestConsensus.cpp | 10 +-
tests/unit/TestIntegrator.cpp | 9 +-
tests/unit/TestLoadModels.cpp | 4 +-
tests/unit/TestPolish.cpp | 2 +-
third-party/cpp-optparse/OptionParser.cpp | 959 ++++++++++-----------
third-party/cpp-optparse/OptionParser.h | 279 ++++--
third-party/cpp-optparse/test.cpp | 277 +++---
third-party/cram-0.7/cram/__init__.py | 6 +
third-party/cram-0.7/cram/__main__.py | 10 +
third-party/cram-0.7/cram/_cli.py | 134 +++
third-party/cram-0.7/cram/_diff.py | 158 ++++
third-party/cram-0.7/cram/_encoding.py | 106 +++
third-party/cram-0.7/cram/_main.py | 211 +++++
third-party/cram-0.7/cram/_process.py | 54 ++
third-party/cram-0.7/cram/_run.py | 77 ++
third-party/cram-0.7/cram/_test.py | 230 +++++
third-party/cram-0.7/cram/_xunit.py | 173 ++++
third-party/cram-0.7/scripts/cram | 9 +
tools/Darwin/clang-format | Bin 2490044 -> 0 bytes
tools/Linux/clang-format | Bin 2754467 -> 0 bytes
tools/check-formatting | 33 -
tools/format-all | 8 -
tools/git-clang-format | 485 -----------
tools/win32/clang-format.exe | Bin 1315328 -> 0 bytes
84 files changed, 3716 insertions(+), 2060 deletions(-)
diff --git a/.gitmodules b/.gitmodules
index fae5e39..461a8eb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,12 +1,16 @@
-[submodule "third-party/htslib"]
- path = third-party/htslib
- url = https://github.com/PacificBiosciences/htslib
- branch = pb
[submodule "third-party/pbbam"]
path = third-party/pbbam
- url = https://github.com/PacificBiosciences/pbbam
+ url = ../pbbam.git
branch = master
[submodule "third-party/seqan"]
- path = third-party/seqan
- url = https://github.com/PacificBiosciences/seqan.git
- branch = master
\ No newline at end of file
+ path = third-party/seqan
+ url = ../seqan.git
+ branch = master
+[submodule "third-party/pbcopper"]
+ path = third-party/pbcopper
+ url = ../pbcopper.git
+ branch = master
+[submodule "third-party/htslib"]
+ path = third-party/htslib
+ url = ../htslib.git
+ branch = pb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 870750f..e172305 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
# UNANIMITY - CHANGELOG
+## [2.0.4]
+
+### Added
+ - Add pbcopper's ToolContract, summary is no longer a second output file
+ - Differentiate between .xml and .bam output type
+ - Enforce .pbi generation
+
+## [2.0.3]
+
+### Added
+ - Switch from cpp-optparse to pbcopper, use pbcopper's CLI parsing
+
## [2.0.2]
### Added
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96ed9fe..264241d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@
##############################################
cmake_policy(SET CMP0048 NEW)
-project(UNANIMITY VERSION 2.0.2 LANGUAGES CXX C)
+project(UNANIMITY VERSION 2.0.4 LANGUAGES CXX C)
cmake_minimum_required(VERSION 3.2)
set(ROOT_PROJECT_NAME ${PROJECT_NAME} CACHE STRING "root project name")
diff --git a/README.md b/README.md
index 721bced..faf66de 100644
--- a/README.md
+++ b/README.md
@@ -41,4 +41,6 @@ This tool will be able to precisely call single-nucleotide variants from consens
## Help
-Issues? Bugs? Please create a github issue.
+Support is only provided for official and stable
+[SMRT Analysis builds](http://www.pacb.com/products-and-services/analytical-software/)
+provided by PacBio and not for source builds.
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..2595f77
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+# Function definitions
+GetBBRepo () {
+ echo "## $1"
+ if [ ! -d $2/$1 ]; then
+ echo "### Clone"
+ ( cd $2 && git clone ssh://git@bitbucket.nanofluidics.com:7999/sat/$1)
+ else
+ echo "### Update"
+ ( cd $2/$1 && git pull)
+ fi
+}
+
+GetGHRepo () {
+ echo "## $1"
+ if [ ! -d $2/$1 ]; then
+ echo "### Clone"
+ ( cd $2 && git clone https://github.com/PacificBiosciences/$1)
+ else
+ echo "### Update"
+ ( cd $2/$1 && git pull)
+ fi
+}
+
+# Main script
+
+echo "#############################"
+echo "# LOAD MODULES"
+source /mnt/software/Modules/current/init/bash
+module load git gcc/5.3.0 python/2.7.9 cmake cram swig ccache virtualenv zlib/1.2.5 ninja boost
+
+echo "#############################"
+echo "# EXTERNAL DEPENDENCIES"
+echo "## Create external dependency directory"
+if [ ! -d _deps ] ; then mkdir _deps ; fi
+echo "## Create reverse external dependency directory"
+if [ ! -d _rev_deps ] ; then mkdir _rev_deps ; fi
+
+GetBBRepo GenomicConsensus _rev_deps
+GetBBRepo ConsensusCore _deps
+GetGHRepo pbcommand _deps
+GetGHRepo pbcore _deps
+GetGHRepo PacBioTestData _deps
+
+echo "## Fetch submodules"
+git submodule update --init --remote
+
+echo "#############################"
+echo "# PRE-BUILD HOOK"
+echo "## Check formatting"
+./tools/check-formatting --all
+
+echo "#############################"
+echo "# VIRTUALENV"
+echo "## Create missing virtualenv"
+if [ ! -d unyve ] ; then /mnt/software/v/virtualenv/13.0.1/virtualenv.py unyve ; fi
+
+echo "## Get into virtualenv"
+source unyve/bin/activate
+
+echo "## Install pip modules"
+pip install --upgrade pip
+pip install numpy cython h5py pysam cram nose jsonschema avro
+( cd _deps/pbcommand && pip install --no-deps . )
+( cd _deps/pbcore && pip install --no-deps . )
+
+echo "## Install PacBioTestData"
+( cd _deps/PacBioTestData && git lfs pull && make python )
+
+echo "#############################"
+echo "# BUILD"
+echo "## Create build directory "
+if [ ! -d build ] ; then mkdir build ; fi
+
+echo "## Build source"
+( cd build &&\
+ rm -rf * &&\
+ CMAKE_BUILD_TYPE=ReleaseWithAssert cmake -DZLIB_INCLUDE_DIR=/mnt/software/z/zlib/1.2.5/include -DZLIB_LIBRARY=/mnt/software/z/zlib/1.2.5/lib/libz.so -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++" -GNinja .. )
+( cd build && ninja htslibSrc )
+( cd build && ninja )
+
+echo "## pip install CC2"
+CMAKE_BUILD_TYPE=ReleaseWithAssert CMAKE_COMMAND=cmake ZLIB_INCLUDE_DIR=/mnt/software/z/zlib/1.2.5/include ZLIB_LIBRARY=/mnt/software/z/zlib/1.2.5/lib/libz.so VERBOSE=1 pip install --verbose --upgrade --no-deps .
+
+echo "## Install ConsensusCore"
+( cd _deps/ConsensusCore && python setup.py install --boost=$BOOST_ROOT )
+
+echo "## Install GC"
+( cd _rev_deps/GenomicConsensus && pip install --upgrade --no-deps --verbose . )
+
+echo "#############################"
+echo "# TEST"
+echo "## Unanimity tests"
+( cd build && ninja check )
+
+echo "## CC2 version test"
+python -c "import ConsensusCore2 ; print ConsensusCore2.__version__"
+
+echo "## Test CC2 via GC"
+( cd _rev_deps/GenomicConsensus && make check )
+
+deactivate
\ No newline at end of file
diff --git a/cmake/uny-dependencies.cmake b/cmake/uny-dependencies.cmake
index 6721d96..a7a7409 100644
--- a/cmake/uny-dependencies.cmake
+++ b/cmake/uny-dependencies.cmake
@@ -4,11 +4,6 @@
# Get static libraries
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-# pbcopper
-# if (NOT pbcopper)
-# add_subdirectory(${UNY_ThirdPartyDir}/pbcopper external/pbcopper/build)
-# endif()
-
# Boost
if(NOT Boost_INCLUDE_DIRS)
find_package(Boost REQUIRED)
@@ -59,4 +54,13 @@ if (NOT PYTHON_SWIG)
if (NOT SEQAN_INCLUDE_DIRS)
set(SEQAN_INCLUDE_DIRS ${UNY_ThirdPartyDir}/seqan/include CACHE INTERNAL "" FORCE)
endif()
+
+ # pbcopper
+ if (NOT pbcopper_INCLUDE_DIRS OR
+ NOT pbcopper_LIBRARIES)
+ set(pbcopper_build_tests OFF CACHE INTERNAL "" FORCE)
+ set(pbcopper_build_docs OFF CACHE INTERNAL "" FORCE)
+ set(pbcopper_build_examples OFF CACHE INTERNAL "" FORCE)
+ add_subdirectory(${UNY_ThirdPartyDir}/pbcopper external/pbcopper/build)
+ endif()
endif()
diff --git a/doc/ConsensusCore2-DesignAndImplementation/ZScoreMath.rst b/doc/ConsensusCore2-DesignAndImplementation/ZScoreMath.rst
new file mode 100644
index 0000000..14d13b9
--- /dev/null
+++ b/doc/ConsensusCore2-DesignAndImplementation/ZScoreMath.rst
@@ -0,0 +1,267 @@
+
+.. _zscore-math:
+
+"Z-Score": when is a read completely garbage?
+---------------------------------------------
+
+Garbage-In-Garbage-Out: It is not always useful to estimate fine-scale
+distinctions when looking at examples that have excessively high
+noise. Estimation is likely to be improved by simplying filtering away
+all examples that are irrecoverably "broken" as long as you still have
+sufficient sample size on which to make estimates.
+
+With "single-molecule-weirdness" such as long bursty inserts,
+individual reads (or subsections of them) might contain very high
+levels of noise. The current record for bursty insert is about 5.7kb
+of inserted sequence that has nothing to do with the reference
+template being sequenced. This can throw off alignments and consensus
+models (CCS2) that do not explicitly model these bursty insert
+behaviours.
+
+While it would be best to solve these behaviors upstream at the
+chemical/polymerase level, we must have defenses in place to at least
+identify when these undesirable behaviors present themselves so we
+might at least try to filter them away before they wreak havoc on
+estimates.
+
+
+Z-Score Motivation
+------------------
+
+The idea is to compute the expected mean and variance of the log
+likelihood (LL) of sequences output by a given HMM. Thus when
+presented with a sequence that has a certain log probability, we can
+reason how far removed it is to "normal" such that outliers can be
+filtered away.
+
+An HMM is a series of Markov steps: transition and emisson. Each step
+will additively change the LL. In a simple left-to-right profile HMM
+with length, :math:`T`, each match/delete will be visited once. It is
+reasonable that sums of log probabilities might be close to normal
+under certain conditions.
+
+Here is the basic HMM structure with match, branch (same match base
+insert), stick (different match base insert), delete:
+
+.. figure:: pacbioHMM.svg.png
+
+ The basic HMM structure of a single match state with match, branch,
+ stick, and delete substates.
+
+For each "substate" (match, delete, branchIns, stickIns) we might
+compute that substate's average contribtuion to the the LL over the
+distribution of outputs induced by the HMM: E[LL] and Var[LL]. Then
+:math:`E[LL] = E[ \sum_{substates} LL] = \sum_{substates} E[LL]` by
+linearity of expectation. For IID substates this is :math:`T*E[LL]`. Var[LL]
+= :math:`Var[ \sum_{substates} LL] = \sum_{substates} Var[LL]` because each
+substate is independent so all covariances are 0. For IID substates
+this is :math:`T*Var[LL]`.
+
+For a motivational example, consider an "HMM" with a single
+multinomial :math:`p=(p_1,p_2,p_3,p_4)`. Here :math:`E[LL] =
+p*log(p).` :math:`E[LL^2] = p*log^2(p).` :math:`Var[LL]=
+E[LL^2]-E^2[LL]` :math:`= p*log^2(p) - (p*log(p))^2`. These are
+expected mean and variance of the LL by this simple multinomial. By
+stringing together multinomial emissions and transitions, we can
+estimate these quantities for an HMM.
+
+An HMM emits a string by entering a state, emitting an output
+according to an emission probability, making a random choice about
+what state to transition to next, transitioning to that new state, and
+repeating.
+
+Consider a single HMM state that has emission probabilities
+:math:`e_j`, transistion probabilities :math:`t_i`, and next state
+:math:`R_i` that outputs the rest of the output. The probability of
+this state is :math:`P=(e_j t_i \prod_k R_{ik})` where the product is
+the rest of the states multiplying their contributions. The log
+likelihood is :math:`LL=\log e_j + \log t_i + \sum_k \log
+R_{ik}`. Define :math:`\log e = \sum_j e_j \log(e_j)` and
+:math:`\log^2 e = \sum_j e_j \log^2(e_j)` be the expectations over the
+possible emission possibitilties.
+
+The expectation of log likelihood is :math:`EXP_{t_i} [(\log e + \log
+t_i + \sum_k \log R_{ik})]`. Note the expecation of the
+log-likelikhood of the rest of the derivation represented by the sum
+is :math:`EXP[ LL(R_i) ]` so we get :math:`EXP_{t_i} [(\log e + \log
+t_i + EXP[ LL(R_i)] ]`
+
+The expectation of log likelihood squared is :math:`EXP_{t_i}[ (\log
+e + \log t_i + \sum_k \log R_{ik})^2]`. Expand the square. The only
+complicating term is :math:`EXP_{t_i}[(\sum_k \log R_{ik})^2]` but we
+realize this to be the expectation of the log-likelihood squared of
+the rest of the derivation, :math:`EXP[ LL^2(R_i) ]`.
+
+Given this, we can write a dynamic program that computes the expected
+log-likelihood and expected log-likelihood squared of
+:math:`thisstate` derving a string of :math:`length` for every state
+and every length up to some maximum. With a large enough maximum
+length computed, contributions from possibly infinite self-loops in
+the insert states will be properly summed as the trailing terms become
+so small as to be negligible.
+
+The relvant python code that computes the expectation over the
+different choices of next rest state (nexts) with transition
+probabilities (nextp) and expected emissions (expEmLL, expEmLL2):
+
+.. code-block:: python
+
+ # cycle through choices
+ overallresult = [0.0, 0.0, 0.0]
+ for ch in range(len(this.nexts)):
+ transp = this.nextp[ch]
+ rhs = self.derive( this.nexts[ch], newlength)
+ A = self.mylog(transp) # log transition
+ A2 = A*A # log transistion squared
+ B = expEmLL # expected log emission likelihood
+ B2= expEmLL2 # expected log squared emission likelihood
+ C = rhs[1] # EXP[LL] of next
+ C2= rhs[2] # EXP[LL^2] of next
+ thisll = transp*(A+B+C)
+ thisll2 = transp*( A2 + B2 + C2 + 2*A*B + 2*A*C +2*B*C)
+ thisprob = transp*rhs[0]
+ if thisprob>0.0:
+ overallresult[0]=overallresult[0]+thisprob
+ overallresult[1]=overallresult[1]+thisll
+ overallresult[2]=overallresult[2]+thisll2
+ self.memo[self.key(thisstate,length)]=overallresult
+ return(overallresult)
+
+
+Z-Score for Filtering
+---------------------
+
+One method for identifying garbage reads is the "Z-Score" described
+here [PBEP_4.pdf]. This result sums out the infinite sums caused by
+the looping insert states analytically to get an analytic result
+rather than a dynamic programming one.
+
+Here is the result verbatim from PBEF_4.pdf:
+
++-------------------------+-----------------------------------------+
+| term | meaning |
++=========================+=========================================+
+| :math:`p_m` | match transistion probability |
++-------------------------+-----------------------------------------+
+| :math:`p_d` | deletion transistion probability |
++-------------------------+-----------------------------------------+
+| :math:`p_s` | stick transition probability |
++-------------------------+-----------------------------------------+
+| :math:`p_b` | branch transition probability |
++-------------------------+-----------------------------------------+
+| :math:`l_m,l_d,l_s,l_b` | log of transition probabilities |
++-------------------------+-----------------------------------------+
+| :math:`E[\rightarrow]` | expected LL from match or deletion |
++-------------------------+-----------------------------------------+
+| :math:`E[\downarrow]` | expected LL from all insertions |
++-------------------------+-----------------------------------------+
+| :math:`E[NN]` | mean LL from context |
++-------------------------+-----------------------------------------+
+| :math:`E[M]` | mean logged match emission probability |
++-------------------------+-----------------------------------------+
+| :math:`E[B]` | mean logged branch emission probability |
++-------------------------+-----------------------------------------+
+| :math:`E[S]` | mean logged stick emission probability |
++-------------------------+-----------------------------------------+
+| :math:`E[I]` | mean logged trans,emiss ins probability |
++-------------------------+-----------------------------------------+
+
+Derivation:
+
+- :math:`E[NN] = E[\downarrow] + E[\rightarrow]`
+
+Break into simple match/delete and insert chains. Expected LL from
+context = expected LL from match/delete + expected LL from insertions
+
+- :math:`E[\rightarrow] = (l_m + E[M]) \frac{p_m}{p_m+p_d} + (l_d) \frac{p_d}{p_m+p_d}`
+
+Transistion weighted (LL from match trans+emis) and (LL from delete
+trans)
+
+- :math:`E[\downarrow]= E[I] \frac{p_s+p_b}{p_m+p_d}`
+
+Expected insertion LL weighted by expected length of insertion where
+:math:`(p_s+p_b)` is the probablity of looping in the insertion and
+:math:`(p_m+p_d)` is the probability of looping out.
+
+- :math:`E[I] = (l_b+E[B]+E[\rightarrow]) \frac{p_b}{p_b+p_s} + (l_s+E[S]+E[\rightarrow]) \frac{p_s}{p_b+p_s}`
+
+Transition weighted LL branch transition/emission and LL stick
+transition/emission within insertion. (Note this updates to three
+terms versus to two in the PBEP)
+
+For the second moment, we replace :math:`LL^2` for :math:`LL` in the
+above equations and are careful to carry the expectation of the
+likelihood or the expectation of the likelihood squared forward.
+
+
++----------------------------------------------------------------------------+
+| Classic Identities: |
++============================================================================+
+| :math:`E[X+Y]=E[X]+E[Y]` |
++----------------------------------------------------------------------------+
+| :math:`Var(X) = E[X^2]-E^2[X]` |
++----------------------------------------------------------------------------+
+| :math:`Var(X+Y) = Var(X) + Var(Y) + 2Cov(X,Y)` |
++----------------------------------------------------------------------------+
+| :math:`E[a*X] = aE[X]` |
++----------------------------------------------------------------------------+
+| :math:`Var(a*X) = a^2Var(X)` |
++----------------------------------------------------------------------------+
+| :math:`E[XY]=E[X]E[Y]` if independent |
++----------------------------------------------------------------------------+
+| :math:`\sum_{k=0}^\infty (1-p)^k*p*k*ll = ll*\frac{1-p}{p}` |
++----------------------------------------------------------------------------+
+| :math:`\sum_{k=0}^\infty (1-p)^k*p*(k*ll)^2 = ll^2 \frac{(p-2)(p-1)}{p^2}` |
++----------------------------------------------------------------------------+
+
+Z-Score Sanity Check
+--------------------
+
+As a sanity check we generated random deviates using a simple HMM with
+varying number of substates, computed means and variances, and
+compared to the computed expected values.
+
+The means and variances are close computed versus estimated.
+
++-------+----------+---------+----------+--------+
+| size | mean | var | compmean | compvar|
++=======+==========+=========+==========+========+
+| 32 |-26.65075 |59.80562 |-27.13874 |68.15969|
++-------+----------+---------+----------+--------+
+| 60 |-50.99983 | 121.535 |-50.88515 |127.7994|
++-------+----------+---------+----------+--------+
+| 120 |-101.8052 |256.4235 |-101.7703 |255.5988|
++-------+----------+---------+----------+--------+
+| 240 |-202.6475 |473.0255 |-203.5406 |511.1977|
++-------+----------+---------+----------+--------+
+| 480 |-407.2655 |1073.169 |-407.0812 |1022.395|
++-------+----------+---------+----------+--------+
+
+Real-world performance on RSII data shows that the Z-score does have
+good performance in filtering garbage reads. Because we are able to
+adjust the Z-Score threshold, good performance is obtained.
+
+Z-Score Shortcomings
+--------------------
+
+The bursty errors occur in localized regions. For a long read, these
+localized bursts might not be detected by the Z-score metric. Overall
+the number of errors, if they were randomly distributed across the
+read, might be within what might be expected normally. The fact that
+they are all localized is what makes it abnormal.
+
+An HMM can identify these localized bursts. The Viterbi path assigns
+each match/delete state to a position in the read
+:math:`(ref_i->read_j \mbox{ with } prob_i)`. Because the HMM is a
+regular language, we know if :math:`ref_i` derives the string starting
+at :math:`read_j` with :math:`prob_i` and :math:`ref_{i+1}` derives
+with :math:`prob_{i+1}` then :math:`ref_i` derives it's portion with
+probability (:math:`prob_i / prob_{i+1}`) (or differences in log
+probability if using log probability). This is the part of the HMM
+that accounts for a single reference base. We can use the same Z-Score
+ideas to determine outliers. If the substate HMM derives 4 or less
+bases 99.999% of the time, then if in the Viterbi path a derivation of
+200 bases is observed, then we can conclude this is an outlier bursty
+insert between this and then next reference base. (Similar ideas exist
+for forward / backward / posterior.)
diff --git a/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.pdf b/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.pdf
new file mode 100644
index 0000000..8834069
Binary files /dev/null and b/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.pdf differ
diff --git a/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.png b/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.png
new file mode 100644
index 0000000..262cb2f
Binary files /dev/null and b/doc/ConsensusCore2-DesignAndImplementation/img/consensus-modalities.png differ
diff --git a/doc/ConsensusCore2-DesignAndImplementation/img/hmms.pdf b/doc/ConsensusCore2-DesignAndImplementation/img/hmms.pdf
new file mode 100644
index 0000000..f4c2b6f
Binary files /dev/null and b/doc/ConsensusCore2-DesignAndImplementation/img/hmms.pdf differ
diff --git a/doc/ConsensusCore2-DesignAndImplementation/img/hmms.png b/doc/ConsensusCore2-DesignAndImplementation/img/hmms.png
new file mode 100644
index 0000000..205f72f
Binary files /dev/null and b/doc/ConsensusCore2-DesignAndImplementation/img/hmms.png differ
diff --git a/doc/ConsensusCore2-DesignAndImplementation/index.rst b/doc/ConsensusCore2-DesignAndImplementation/index.rst
index 7d7dc44..241572c 100644
--- a/doc/ConsensusCore2-DesignAndImplementation/index.rst
+++ b/doc/ConsensusCore2-DesignAndImplementation/index.rst
@@ -2,8 +2,9 @@
``ConsensusCore2``: design and implementation
===========================================
-Authors: David Alexander, Nigel Delaney, Lance Hepler, Armin Töpfer
-Last modified: July 27, 2016
+
+| **Authors:** David Alexander, Michael Brown, Nigel Delaney, Lance Hepler, Armin Töpfer
+| **Last modified:** August 10, 2016
Motivation
@@ -32,9 +33,9 @@ framework, asking the question "what is the probability that an
underlying *template* sequence T generated an observed read sequence
R?", and then using the model :math:`\Pr(R \mid T)` to answer the
multi-read consensus problem via maximum likelihood---the consensus
-sequence then mathematically defined as :math:`\arg\max_T \Pr(T \mid
-\mathbf{R})`, where :math:`\mathbf{R}` represents the vector of
-multiple reads.
+sequence then mathematically defined as :math:`\arg\max_T
+\Pr(\mathbf{R} \mid T)`, where :math:`\mathbf{R}` represents the
+vector of multiple reads.
Such a likelihood model is implemented using standard techniques from
the hidden Markov model (HMM) literature. The likelihood model is
@@ -42,8 +43,8 @@ made tractable by approximating full dynamic programming using
banding, and, critically, the maximum likelihood search is made
tractable using a greedy search and a core routine using a
forward-backward identity that enables fast (:math:`O(1)`)
-recalculation of the likelihood when the template is mutated pointwise
-from :math:`T` to :math:`T+\mu`.
+recalculation of the likelihood when the template is mutated pointwise,
+:math:`T \to T+\mu`.
The consensus problem has multiple guises, as we have mentioned. In
the *circular consensus sequence* application (*CCS*), multiple
@@ -60,7 +61,11 @@ the reference genome. In the context of a "draft" assembly, the
application is referred to as "polishing" and the goal is simply to
produce the most accurate sequence of the genome as possible.
-[add picture here]
+.. figure:: img/consensus-modalities.*
+ :width: 100%
+
+ *Consensus can applied in a single-molecule or multi-molecule
+ context, for different applications.*
Additionally, the mathematical model of :math:`Pr(T \mid \mathbf{R})`
has immediate applications even beyond the single-template consensus
@@ -73,70 +78,292 @@ estimation, as well as haplotype phasing. The latter problem is
History
-------
-An initial consensus model (names `Quiver` in 2012) was originated in
+An initial consensus model (named `Quiver` in 2012) was originated in
the original CCS implementation (ca. 2010) and proved capable of
generating consensus sequences with accuracy near Q25 provided enough
evidence---enough "passes" of the insert DNA. The initial codebase
was in C# with some routines in C/C++. In 2012-2013, the core of the
Quiver consensus algorithm was exported to a C++ library,
-`ConsensusCore`, which provided SWIG bindings to higher-level host
+``ConsensusCore``, which provided SWIG bindings to higher-level host
languages (Python and C#, in chief), enabling use from other
applications . The C# algorithm implementation was replaced by calls
-to the `ConsensusCore` library; simultaneously, a Python application
+to the ``ConsensusCore`` library; simultaneously, a Python application
(``GenomicConsenus``) was developed for applications in genome
assembly polishing, yielding very successful results: over Q50 (and in
some cases, over Q60) accuracy achieved on bacterial genome
assemblies.
-The arrival of the ``GenomicConsensus" application coincided roughly
+The arrival of the ``GenomicConsensus`` application coincided roughly
with the initial development of HGAP (the Hierarchical Genome Assembly
Program), thus offering fast end-to-end genome assembly with
exceptionally high quality results, establishing PacBio as a player in
the fields of "sequence finishing" and microbiology in 2013.
-Throughput improvements would
+Throughput improvements over time then made PacBio assembly appealing
+for larger genomes, including fungi, plants, and animals.
Analyses of CCS results using the Quiver model showed evidence that
CCS was far from a solved problem. First of all, the accuracy of CCS
results were found to fall short of the accuracy from multi-molecule
consensus sequences with comparable "coverage" in multiple controlled
experiments. Perhaps more troubling, it was observed that consensus
-accuracy "saturated", failing to increase beyond a certain point when
+accuracy "saturated", failing to increase beyond a certain number of
+passes.
+
+Experiments suggested that part of this problem was due to a failure
+to account for ZMW-specific variables in the Quiver model; "genomic"
+consensus was not subject to this problem because multiple molecules
+would counterbalance each other. Another defect of the Quiver model
+was that it was trained in a "discriminative" fashion, which we
+believe biased the model in a manner that prevented convergence to
+perfect accuracy as the number of CCS passes increased.
+
+In addition to the deficiencies in accuracy, the Quiver model also was
+burdensome from the a software engineering perspective. It was
+unusable as an "inference" tool---there was no way to use it to
+estimate underlying physical sequencing HMM parameters (merge rates,
+for example); a completely separate codebase and tool (EDNA) was used
+for this purpose---imposing a maintenance burden. Furthermore, the
+nonstandard derivative-free optimization method that was used to train
+Quiver was slow and unreliable, making it unsuitable for use in an
+automated training pipeline.
+
+These observations motivated the development of a new model, based on
+standard likelihood theory and standard training techniques, and
+suitable as an inference tool to replace EDNA. This was the "UniteEM"
+effort led by Nigel Delaney, resulting in the "Arrow" model.
+
The Arrow model
---------------
-Differences from Quiver...
-
+The Quiver model was effectively a "conditional random field" over
+multivariate observations that encompassed the base calls and multiple
+additional "QV" tracks emitted by the basecaller. However it was not
+trained in a standard manner; rather it was trained using an
+unreliable and slow derivative-free optimizaton and with an objective
+function that reflected a non-standard likelihood function more akin
+to a classification accuracy. Furthermore, its ability to adapt to
+the
+
+The Arrow model is a complete reboot. It is a left-right HMM model,
+very similar to the standard textbook left-right sequence "profile"
+HMM. Arrow differs from those models in a few key ways. First, while
+the standard profile HMM just models sequence alignment moves (Match,
+Insert, Delete), Arrow models the enzymatic and photophysical events
+(Sticks, Branches, (Mis)incorporations, Merges, and "dark" pulses)
+underlying such moves in SMRT sequencing. Secondly, emission and
+transition parameters are not estimated independently for every state;
+rather the states are "tied" by the dinucleotide template context.
+Third, the transition parameters are "tied", depending only on the
+template position and not on the state the model is in; this
+simplification enables computing the model using a single matrix
+matrix instead of one per state type.
+
+.. figure:: img/hmms.*
+ :width: 100%
+
+ *The standard profile HMM (A) uses states to model alignment moves
+ (Match, Insert, Delete), while the Arrow HMM (B) models the
+ underlying physical events (which themselves give rise to
+ "alignment" moves). Otherwise, the models are quite similar.*
+
+While the Arrow model can be used to estimate transition and emission
+parameters freely for each read (the "EDNA" use case), in the more
+common case emission parameters are only estimated per dinucleotide
+context, combining all reads, while the transition probability
+parameters are expected to follow a regression model on a few scalar
+read covariates (at present, the only covariate used in this manner is
+the read's SNR).
+
+The Arrow model is trained using the standard Baum-Welch EM algorithm
+procedure; the only extension here is that when the SNR is used as a
+covariate, the M step requires maximum likelihood estimation of
+a multinomial logistic model.
+
+.. todo:: probably wise to include some actual math here!
+
+
+
+Algorithm overview
+------------------
Implementation
--------------
Draft consensus by partial-order alignment
-``````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
The essence: calculating, and re-calculating, likelihood
-````````````````````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Indexing conventions and matrix display convention (tpl on top, read
+ on side)
+
+
+
+
+Practical and numerical aspects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Scaling vs log-domain math
+``````````````````````````
+
+The naive approach to computing likelihoods in an HMM inevitably runs
+afoul of numerical underflow, as many probabilities are multiplied
+together. The standard practical solutions are to compute all matrix
+entries (probabilities) in the log-domain, or to scale each row or
+column
+
+The choice of scaling or log-domain math has implications for the math
+required in the different calculations we need to perform. For the
+Sum-Product recursion...
+
+
+Banding
+```````
+
+Computing the entire dynamic-programming matrices is prohibitively
+expensive in memory and CPU time, given the number and size of
+matrices we need to compute. Rather, we use a *banded dynamic
+programming* approach where we only compute and retain a high-scoring
+band in each matrix column; these bands should capture all of the
+plausible alignment paths describing how T induces R.
+
+Banding is presently performed "on the fly", as the matrix (alpha or
+beta) itself is filled. The column is filled, starting from the first
+filled row of the previous column, and we continue to fill it until it
+falls below the maximum score in the column by more than
+``scoreDiff``. Finally, we scan back to identify the first row in the
+column within ``scoreDiff`` of the max. This interval is then
+recorded as the nominally "filled" band of the column.
+
+An important requirement of the banding is that the bands of the
+forward (alpha) and backward (beta) matrices must be concordant,
+meaning that they overlap sufficiently such that the forward-backward
+identity can still hold despite the bands. Another way of looking at
+this is that *all* high probability paths in alpha must be calculated
+in beta, and vice versa, so that the "link" operation can find a path.
+
+In practice, we check for correct "mating" of the alpha and beta
+matrices by first
+
+check whether the
+
+
+In the future we hope to adopt a *pre-banding* approach where we
+identify the likely high-scoring bands by a preliminary SDP step.
+Ideally, this will eliminate the need for flip-flopping, simplify the
+inner loop of the recursions, and
-Numerical aspects
-`````````````````
-Scaling vs log-domain math.
+Counterweights
+``````````````
-The counterweights.
+It is interesting to consider the score of the path that proceeds
+through the alpha matrix along the top row, then finally moving down
+to the bottom-right entry when it reaches the last column. This can
+be thought of as an "alignment" that "deletes" all the template bases,
+then "inserts" the read bases in at the end. This is a poor alignment
+by any estimation, but it defeats our "on the fly" banding procedure.
+.. todo:: picture here, showing the path and its two segments
-Setup for calling consensus: the `Integrator` classes
-`````````````````````````````````````````````````````
+In particular, note that the segment 1 describes a path through the
+Markov model that produces no emissions. The likelihood for this
+segment then has many fewer multiplicative probability factors than
+segments that move downward. Unless the transition probability into
+or from the delete state is sufficiently low---which is in no way
+guaranteed by the HMM or its training---then, these paths to the right
+will seem locally favorable---the penalty is not felt until the
+emissions must be made later. The greedy "on the fly" banding
+procedure thus may
+
+This problem presents itself as excessively wide bands, spanning from
+near the diagonal to the path 1->2.
+
+Presently, we avoid this problem by artificially penalizing deletions
+(or, alternately, by encouraging emissions) using what we term a
+*counterweight*: a constant positive value added to the score of each
+matrix cell for each emission, used for purposes of band calculation
+only.
+
+If we adopt pre-banding, we can eliminate the need for using
+counterweights.
+
+
+Batching of mutations
+`````````````````````
+
+
+Coding conventions
+~~~~~~~~~~~~~~~~~~
+
+Setup for calling consensus: the ``Integrator`` classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The basic setup for computing a consensus sequence from reads (and a
+draft consensus) is to build an ``Integrator`` object. There are two
+``Integrator`` classes: the ``MultiMolecularIntegrator`` and the
+``MonoMolecularIntegrator``, which are optimized, respectively, for
+the multimolecule and CCS use cases. An abstract base class
+``AbstractIntegrator`` factors out some common functionality and
+simplifies life for client code. After creating an integrator for a
+given model configuration and template DNA sequence hypothesis, client
+code then adds ``MappedRead`` objects to the integrator;
+``MappedRead`` objects represent the read data (including covariates)
+and also indicate the start/end positions where it is anchored on the
+template sequence. Once this is done, client code then calls the
+``Polish`` function, which performs the iterative greedy search
+procedure, returning a ``PolishResult`` object recording iteration
+count and other metrics, while as a side effect updating the
+``Integrator`` object to point at the maximum likelihood consensus.
+
+``Integrator`` objects support polishing by exposing methods that
+enable testing, and commiting, mutations to the underlying template.
+This requires a good deal of bookkeeping internally, as each mutation
+applied requires potential updates to the read-to-template anchor
+mappings.
+
+
+The workhorse: the Recursor class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The template classes
+~~~~~~~~~~~~~~~~~~~~
Model lookup
-````````````
+~~~~~~~~~~~~
Model parameter lookup
-``````````````````````
+~~~~~~~~~~~~~~~~~~~~~~
Training
-````````
+~~~~~~~~
+
+
+
+
+Identifying (and removing) abberant reads: the "ZScore" concept
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Basic explanation goes here.
+
+For the mathematical details of how the variance and expectation are
+calculated, see :ref:`zscore-math`.
+
+
+
+Appendices: the gory details
+----------------------------
+
+.. toctree::
+ :maxdepth: 1
+
+ ZScoreMath
+ CounterWeightMath
diff --git a/doc/ConsensusCore2-DesignAndImplementation/pacbioHMM.svg.png b/doc/ConsensusCore2-DesignAndImplementation/pacbioHMM.svg.png
new file mode 100644
index 0000000..998015f
Binary files /dev/null and b/doc/ConsensusCore2-DesignAndImplementation/pacbioHMM.svg.png differ
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index 443c1e7..b7ad820 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -17,7 +17,7 @@ automates dependency fetching/resolution:
### All tools: manually
-Building from scratch requires system-wide installed boost (>=1.5.8),
+Building from scratch requires system-wide installed boost (>=1.58.0),
cmake (3.2), and a c++11 compiler (>=gcc-5.3.0, clang):
```sh
@@ -36,12 +36,19 @@ cmake (3.2), and a c++11 compiler (>=gcc-5.3.0, clang):
Invoke the different `make` targets, currently available
```sh
- $ make pbccs
+ git clone https://github.com/PacificBiosciences/unanimity && \
+ cd unanimity && \
+ git submodule update --init --remote && \
+ mkdir build && \
+ cd build && \
+ cmake .. && \
+ make ccs && \
+ ./ccs
```
### Install ConsensusCore2 python library for GenomicConsensus
-Building from scratch requires system-wide installed boost (>=1.5.8),
+Building from scratch requires system-wide installed boost (>=1.58.0),
cmake (3.2), python 2.x, and a c++11 compiler (>=gcc-5.3.0, clang):
```sh
diff --git a/include/pacbio/ccs/Consensus.h b/include/pacbio/ccs/Consensus.h
index d2a5110..5cf998c 100644
--- a/include/pacbio/ccs/Consensus.h
+++ b/include/pacbio/ccs/Consensus.h
@@ -49,8 +49,7 @@
#include <boost/optional.hpp>
-#include <OptionParser.h>
-
+#include <pacbio/ccs/ConsensusSettings.h>
#include <pacbio/consensus/MonoMolecularIntegrator.h>
#include <pacbio/consensus/Polish.h>
#include <pacbio/data/State.h>
@@ -86,90 +85,6 @@ using SparsePoa = PacBio::Poa::SparsePoa;
using AlignConfig = PacBio::Align::AlignConfig;
using AlignMode = PacBio::Align::AlignMode;
-namespace OptionNames {
-// constexpr auto MaxPoaCoverage = "maxPoaCoverage";
-constexpr auto MaxLength = "maxLength";
-constexpr auto MinLength = "minLength";
-constexpr auto MinPasses = "minPasses";
-constexpr auto MinPredictedAccuracy = "minPredictedAccuracy";
-constexpr auto MinZScore = "minZScore";
-constexpr auto MaxDropFraction = "maxDropFraction";
-constexpr auto NoPolish = "noPolish";
-constexpr auto MinReadScore = "minReadScore";
-constexpr auto MinSnr = "minSnr";
-constexpr auto ByStrand = "byStrand";
-} // namespace OptionNames
-
-struct ConsensusSettings
-{
- size_t MaxPoaCoverage;
- size_t MaxLength;
- size_t MinLength;
- size_t MinPasses;
- double MinPredictedAccuracy;
- double MinZScore;
- double MaxDropFraction;
- bool ByStrand;
- bool NoPolish;
- double MinReadScore;
- double MinSNR;
-
- ConsensusSettings(const optparse::Values& options);
-
- static void AddOptions(optparse::OptionParser* const parser)
- {
- const std::string em = "--";
- // TODO(lhepler) implement alignment to POA
- // parser->add_option(em +
- // OptionNames::MaxPoaCoverage).type("int").set_default(1024).help("Maximum number of
- // subreads to use when building POA. Default = %default");
- parser->add_option(em + OptionNames::MaxLength)
- .type("int")
- .set_default(7000)
- .help("Maximum length of subreads to use for generating CCS. Default = %default");
- parser->add_option(em + OptionNames::MinLength)
- .type("int")
- .set_default(10)
- .help("Minimum length of subreads to use for generating CCS. Default = %default");
- parser->add_option(em + OptionNames::MinPasses)
- .type("int")
- .set_default(3)
- .help("Minimum number of subreads required to generate CCS. Default = %default");
- parser->add_option(em + OptionNames::MinPredictedAccuracy)
- .type("float")
- .set_default(0.90)
- .help("Minimum predicted accuracy in [0, 1]. Default = %default");
- parser->add_option(em + OptionNames::MinZScore)
- .type("float")
- .set_default(-3.5)
- .help("Minimum z-score to use a subread. NaN disables this filter. Default = %default");
- parser->add_option(em + OptionNames::MaxDropFraction)
- .type("float")
- .set_default(0.34)
- .help(
- "Maximum fraction of subreads that can be dropped before giving up. Default = "
- "%default");
- parser->add_option(em + OptionNames::MinSnr)
- .type("float")
- .set_default(
- 3.75) // See https://github.com/PacificBiosciences/pbccs/issues/86 for a more
- // detailed discussion of this default.
- .help("Minimum SNR of input subreads. Default = %default");
- parser->add_option(em + OptionNames::MinReadScore)
- .type("float")
- .set_default(0.75)
- .help("Minimum read score of input subreads. Default = %default");
- parser->add_option(em + OptionNames::ByStrand)
- .action("store_true")
- .help("Generate a consensus for each strand. Default = false");
- parser->add_option(em + OptionNames::NoPolish)
- .action("store_true")
- .help(
- "Only output the initial template derived from the POA (faster, less accurate). "
- "Default = false");
- }
-};
-
template <typename TId>
struct ReadType
{
diff --git a/src/Consensus.cpp b/include/pacbio/ccs/ConsensusSettings.h
similarity index 55%
copy from src/Consensus.cpp
copy to include/pacbio/ccs/ConsensusSettings.h
index a74e0f8..3e298c4 100644
--- a/src/Consensus.cpp
+++ b/include/pacbio/ccs/ConsensusSettings.h
@@ -33,29 +33,57 @@
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
-// Author: Lance Hepler
+// Author: Lance Hepler, Armin Töpfer
+#pragma once
-#include <limits>
+#include <algorithm>
+#include <string>
+#include <thread>
-#include <pacbio/ccs/Consensus.h>
+#include <pbcopper/cli/CLI.h>
+
+#include <pacbio/data/PlainOption.h>
namespace PacBio {
namespace CCS {
-ConsensusSettings::ConsensusSettings(const optparse::Values& options)
- : MaxPoaCoverage{std::numeric_limits<size_t>::max()}
- , MaxLength{options.get(OptionNames::MaxLength)}
- , MinLength{options.get(OptionNames::MinLength)}
- , MinPasses{options.get(OptionNames::MinPasses)}
- , MinPredictedAccuracy{options.get(OptionNames::MinPredictedAccuracy)}
- , MinZScore{options.get(OptionNames::MinZScore)}
- , MaxDropFraction{options.get(OptionNames::MaxDropFraction)}
- , ByStrand{options.get(OptionNames::ByStrand)}
- , NoPolish{options.get(OptionNames::NoPolish)}
- , MinReadScore{static_cast<float>(options.get(OptionNames::MinReadScore))}
- , MinSNR{static_cast<double>(options.get(OptionNames::MinSnr))}
+/// This class contains all command-line provided arguments and additional
+/// constants. Provides a static function to create the CLI pbcopper Interface
+/// and the constructor resovlves the CLI::Results automatically.
+struct ConsensusSettings
{
-}
+ bool ByStrand;
+ const size_t ChunkSize = 1;
+ bool ForceOutput;
+ std::string LogFile;
+ std::string LogLevel;
+ double MaxDropFraction;
+ size_t MaxLength;
+ const size_t MaxPoaCoverage = std::numeric_limits<size_t>::max();
+ size_t MinLength;
+ size_t MinPasses;
+ double MinPredictedAccuracy;
+ double MinReadScore;
+ double MinSNR;
+ double MinZScore;
+ std::string ModelPath;
+ std::string ModelSpec;
+ bool NoPolish;
+ size_t NThreads;
+ bool PbIndex;
+ std::string ReportFile;
+ bool RichQVs;
+ std::string WlSpec;
+
+ /// Parses the provided CLI::Results and retrieves a defined set of options.
+ ConsensusSettings(const PacBio::CLI::Results& options);
-} // namespace CCS
-} // namespace PacBio
+ size_t ThreadCount(int n);
+
+ /// Given the description of the tool and its version, create all
+ /// necessary CLI::Options for the ccs executable.
+ static PacBio::CLI::Interface CreateCLI(const std::string& description,
+ const std::string& version);
+};
+}
+} // ::PacBio::CCS
\ No newline at end of file
diff --git a/include/pacbio/consensus/AbstractIntegrator.h b/include/pacbio/consensus/AbstractIntegrator.h
index 6ed3fd8..536ff33 100644
--- a/include/pacbio/consensus/AbstractIntegrator.h
+++ b/include/pacbio/consensus/AbstractIntegrator.h
@@ -49,9 +49,10 @@
namespace PacBio {
namespace Consensus {
-
+// Forward decl
class AbstractMatrix;
+/// Contains user-provided filtering information for the Evaluators.
struct IntegratorConfig
{
double MinZScore;
@@ -60,6 +61,8 @@ struct IntegratorConfig
IntegratorConfig(double minZScore = -3.5, double scoreDiff = 12.5);
};
+/// At its core, this class holds a vector of Evaluators and provides helper
+/// functions to execute certain actions on each Evaluator.
class AbstractIntegrator
{
public:
@@ -83,21 +86,30 @@ public:
virtual PacBio::Data::State AddRead(const PacBio::Data::MappedRead& read) = 0;
- // For debugging purposes
- // (Note that these include results include all evaluators, even the inactive ones)
+ /// Given a Mutation of interest, returns a vector of LLs,
+ /// one LL per Evaluator, even for inactive ones.
std::vector<double> LLs(const Mutation& mut);
+ /// Using the current template, returns a vector of LLs,
+ /// one LL per Evaluator, even for inactive ones.
std::vector<double> LLs() const;
+ /// For each Evaluator, returns the read name.
std::vector<std::string> ReadNames() const;
-
+ /// Returns the number of flip flop events for each Evaluator.
std::vector<int> NumFlipFlops() const;
+ /// Returns the maximal number of flip flop events of all Evaluators.
int MaxNumFlipFlops() const;
-
+ /// Computes the ratio of populated cells in the alpha matrix for each
+ /// Evaluator and returns the maximal ratio.
float MaxAlphaPopulated() const;
+ /// Computes the ratio of populated cells in the beta matrix for each
+ /// Evaluator and returns the maximal ratio.
float MaxBetaPopulated() const;
-
+ /// Returns the state of each Evaluator.
std::vector<PacBio::Data::State> States() const;
+ /// Returns the strand of each Evaluator.
std::vector<PacBio::Data::StrandType> StrandTypes() const;
+ /// Returns read-only access to Evaluator idx.
const Evaluator& GetEvaluator(size_t idx) const;
public:
diff --git a/include/pacbio/consensus/AbstractMatrix.h b/include/pacbio/consensus/AbstractMatrix.h
index dc67585..cc2ac51 100644
--- a/include/pacbio/consensus/AbstractMatrix.h
+++ b/include/pacbio/consensus/AbstractMatrix.h
@@ -38,19 +38,18 @@
namespace PacBio {
namespace Consensus {
-// AbstractMatrix is a superclass of the matrix types used in the arrow
-// banded dynamic programming. It exposes a minimal interface only
-// intended for diagnostic purposes (looking at a matrix from Python,
-// seeing how well the banding is working, ...). No matrix implementation
-// details are exposed---one can think of this as effectively an opaque
-// data type.
+/// AbstractMatrix is a superclass of the matrix types used in the arrow
+/// banded dynamic programming. It exposes a minimal interface only
+/// intended for diagnostic purposes (looking at a matrix from Python,
+/// seeing how well the banding is working, ...). No matrix implementation
+/// details are exposed---one can think of this as effectively an opaque
+/// data type.
class AbstractMatrix
{
public:
- // Method SWIG clients can use to get a native matrix (e.g. Numpy)
- // mat must be filled as a ROW major matrix, and the understanding
- // is that the entries represent natural-logs of probabilities.
- // N.B.: Needs int, not size_t dimensions, for SWIG/numpy
+ /// Method SWIG clients can use to get a native matrix (e.g. Numpy)
+ /// mat must be filled as a ROW major matrix.
+ /// N.B.: Needs int, not size_t dimensions, for SWIG/numpy
virtual void ToHostMatrix(double** mat, int* rows, int* cols) const = 0;
public:
diff --git a/include/pacbio/consensus/Evaluator.h b/include/pacbio/consensus/Evaluator.h
index 71e6125..2804343 100644
--- a/include/pacbio/consensus/Evaluator.h
+++ b/include/pacbio/consensus/Evaluator.h
@@ -39,6 +39,7 @@
#include <utility>
#include <vector>
+#include <pacbio/consensus/MatrixViewConvention.h>
#include <pacbio/consensus/Template.h>
#include <pacbio/data/Read.h>
#include <pacbio/data/State.h>
@@ -50,56 +51,117 @@ namespace Consensus {
class EvaluatorImpl;
class AbstractMatrix;
+/// Each Evaluator holds one reference to a MappedRead and its Template.
+/// An Evaluator can compute the LL that its MappedRead stems from the Template.
+/// Core functionality: compute the LL given a temporary mutated Template
+/// and apply mutations to the Template.
+///
+/// A PIMPL wrapper around the implementation of the Evaluator allows to
+/// deactivate the instance, either implicitly by an error or
+/// expliciltly by releasing the implementation pointer.
+///
+/// If a function gets called on an deactivated Evaluator, it returns -INF!
class Evaluator
{
public:
Evaluator() = delete;
+
+ /// Initializes an empty instance as a placeholder.
explicit Evaluator(PacBio::Data::State);
+
+ /// Default constructor.
+ ///
+ /// \param tpl The respective template.
+ /// \param mr The MappedRead
+ /// \param minZScore The minimum z-score
+ /// \param scoreDiff The score difference
Evaluator(std::unique_ptr<AbstractTemplate>&& tpl, const PacBio::Data::MappedRead& mr,
double minZScore, double scoreDiff);
- // copying is verboten
+ /// Copying is verboten
Evaluator(const Evaluator&) = delete;
Evaluator& operator=(const Evaluator&) = delete;
- // move constructor
+ /// Move constructor
Evaluator(Evaluator&&);
- // move assign operator
+ /// Move assign operator
Evaluator& operator=(Evaluator&&);
+ /// Destructor
~Evaluator();
size_t Length() const; // TODO: is this used anywhere? If not, delete it.
+
+ /// Returns the strand if Evaluator.
+ /// Return StrandType::UNMAPPED if deactivated.
PacBio::Data::StrandType Strand() const;
+ /// Returns if the Evaluator is valid.
operator bool() const { return IsValid(); }
+
+ /// Returns if the Evaluator is still valid and active.
bool IsValid() const { return curState_ == PacBio::Data::State::VALID; }
+ /// TODO: Attention, not implemented, thus can be removed.
operator std::string() const;
+
+ /// Returns the read name.
+ /// Returns *Inactive evaluator* if deactivated.
std::string ReadName() const;
+ /// Returns the LL of the Read, given the mutated template.
+ /// Returns -INF if deactivated.
double LL(const Mutation& mut);
+
+ /// Returns the LL of the Read, given the current template.
+ /// Returns -INF if deactivated.
double LL() const;
+ /// Returns the mean and variance over all site-wise normal parameters.
+ /// Returns {-INF, -INF} if deactivated.
std::pair<double, double> NormalParameters() const;
+ /// Returns the ZScore of this Evaluator's LL, given all Evaluators of
+ /// the template.
+ /// Returns -INF if deactivated.
double ZScore() const;
+ /// Applies a single mutation to the template.
+ /// Returns if mutation has been applied
+ /// and deactivates the Evaluator if not.
bool ApplyMutation(const Mutation& mut);
+
+ /// Applies a vector of mutations to the template.
+ /// Returns if all mutations have been applied
+ /// and deactivates the Evaluator if not.
bool ApplyMutations(std::vector<Mutation>* muts);
+ /// Returns the current state of the Evaluator.
PacBio::Data::State Status() const { return curState_; }
+
+ /// Returns number of flip flop events from the initial alpha/beta fill.
+ /// Returns -INF if deactivated.
int NumFlipFlops() const;
+ /// Invalides this Evaluator and releases its implementation.
void Release();
public:
const AbstractMatrix& Alpha() const;
const AbstractMatrix& Beta() const;
+ const AbstractMatrix* AlphaView(MatrixViewConvention c) const;
+ const AbstractMatrix* BetaView(MatrixViewConvention c) const;
+
private:
+ /// Checks the z-score and disables the Evaluator if does not pass
+ /// the threshold.
+ /// This filter noops for Sequel models.
void CheckZScore(const double minZScore, const std::string& model);
+ /// Sets the state of the Evaluator.
+ /// Allows transition from VALID to anything and from anything to DISABLED.
+ /// Disables the Evaluator if not VALID.
void Status(PacBio::Data::State nextState);
private:
diff --git a/src/align/AlignConfig.cpp b/include/pacbio/consensus/MatrixViewConvention.h
similarity index 76%
copy from src/align/AlignConfig.cpp
copy to include/pacbio/consensus/MatrixViewConvention.h
index 7f24eeb..14cdd41 100644
--- a/src/align/AlignConfig.cpp
+++ b/include/pacbio/consensus/MatrixViewConvention.h
@@ -33,26 +33,27 @@
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
-// Authors: David Alexander, Lance Hepler
+// Author: David Alexander
-#include <pacbio/align/AlignConfig.h>
+#pragma once
namespace PacBio {
-namespace Align {
+namespace Consensus {
-AlignParams::AlignParams(int match, int mismatch, int insert, int delete_)
- : Match(match), Mismatch(mismatch), Insert(insert), Delete(delete_)
+enum class MatrixViewConvention
{
-}
-AlignParams AlignParams::Default() { return AlignParams(0, -1, -1, -1); }
+ AS_IS, // View the matrix entries exactly as
+ // stored.
-AlignConfig::AlignConfig(AlignParams params, AlignMode mode) : Params(params), Mode(mode) {}
+ LOGSPACE, // View matrix entries in logspace;
+ // includes column scaling factors.
-AlignConfig AlignConfig::Default()
-{
- return AlignConfig(AlignParams::Default(), AlignMode::GLOBAL);
-}
+ LOGPROBABILITY, // View matrix entries as log-scaled
+ // probabilities. This entails scaling
+ // per-column and per-row
+ // (counterweights...).
-} // namespace Consensus
-} // namespace PacBio
+};
+}
+}
diff --git a/include/pacbio/consensus/MonoMolecularIntegrator.h b/include/pacbio/consensus/MonoMolecularIntegrator.h
index b9d521f..1209d02 100644
--- a/include/pacbio/consensus/MonoMolecularIntegrator.h
+++ b/include/pacbio/consensus/MonoMolecularIntegrator.h
@@ -50,9 +50,17 @@
namespace PacBio {
namespace Consensus {
+/// The MONO-molecular integrator holds all Evaluators of a single ZMW,
+/// sharing the one Template, the CCS consensus sequence.
class MonoMolecularIntegrator : public AbstractIntegrator
{
public:
+ /// \brief Initialize the MonoMolecularIntegrator.
+ ///
+ /// \param tpl The draft template as a string
+ /// \param cfg The configuration used to initialize the AbstractIntegrator.
+ /// \param snr The snr
+ /// \param model The model
MonoMolecularIntegrator(const std::string& tpl, const IntegratorConfig& cfg,
const PacBio::Data::SNR& snr, const std::string& model);
@@ -61,14 +69,19 @@ public:
size_t TemplateLength() const override;
+ /// Returns base i of the template
char operator[](size_t i) const override;
operator std::string() const override;
+ /// Computes the LL sum of all Evaluators, given a templated mutated by mut.
double LL(const Mutation& mut) override;
+ /// Computes the LL sum of all Evaluators, given the current template.
inline double LL() const override { return AbstractIntegrator::LL(); }
+ /// Applies a mutation to the template of each Evaluator.
void ApplyMutation(const Mutation& mut) override;
+ /// Applies a vector of murations to the template of each Evaluator.
void ApplyMutations(std::vector<Mutation>* muts) override;
-
+ /// Encapsulate the read in an Evaluator and stores it.
PacBio::Data::State AddRead(const PacBio::Data::MappedRead& read) override;
protected:
diff --git a/include/pacbio/consensus/MultiMolecularIntegrator.h b/include/pacbio/consensus/MultiMolecularIntegrator.h
index a97dcf3..8b07aca 100644
--- a/include/pacbio/consensus/MultiMolecularIntegrator.h
+++ b/include/pacbio/consensus/MultiMolecularIntegrator.h
@@ -51,19 +51,28 @@
namespace PacBio {
namespace Consensus {
+/// The MULTI-molecular integrator holds those Evaluators, whose MappedReads
+/// belong to the same genomic region, but do not share the same template.
class MultiMolecularIntegrator : public AbstractIntegrator
{
public:
+ /// \brief Initialize the MultiMolecularIntegrator.
+ ///
+ /// \param tpl The draft template as a string
+ /// \param cfg The configuration used to initialize the AbstractIntegrator.
MultiMolecularIntegrator(const std::string& tpl, const IntegratorConfig& cfg);
size_t TemplateLength() const override;
+ /// Returns base i of the template
char operator[](size_t i) const override;
operator std::string() const override;
+ /// Applies a mutation to the template of each Evaluator.
void ApplyMutation(const Mutation& mut) override;
+ /// Applies a vector of murations to the template of each Evaluator.
void ApplyMutations(std::vector<Mutation>* muts) override;
-
+ /// Encapsulate the read in an Evaluator and stores it.
PacBio::Data::State AddRead(const PacBio::Data::MappedRead& read) override;
protected:
diff --git a/include/pacbio/consensus/Mutation.h b/include/pacbio/consensus/Mutation.h
index a965f2b..e51e472 100644
--- a/include/pacbio/consensus/Mutation.h
+++ b/include/pacbio/consensus/Mutation.h
@@ -45,6 +45,7 @@
namespace PacBio {
namespace Consensus {
+/// Enum with all possible mutation types
enum struct MutationType : uint8_t
{
DELETION,
@@ -57,6 +58,8 @@ enum struct MutationType : uint8_t
// forward decl
class ScoredMutation;
+/// Encapsulates the type of the mutation, the start position, and an
+/// alternative base.
class Mutation
{
public:
@@ -73,15 +76,20 @@ public:
bool IsAnySubstitution() const;
size_t Start() const;
+ /// Returns the end position of the mutation that is start + 1,
+ /// except for insertions.
size_t End() const;
+ /// Returns the length difference introduced by this mutation.
int LengthDiff() const;
bool operator==(const Mutation& other) const;
operator std::string() const;
+ /// Uses this and the provided score to create and return a ScoredMutation.
ScoredMutation WithScore(double score) const;
+ /// Comparer to sort mutations by start/end.
static bool SiteComparer(const Mutation& lhs, const Mutation& rhs)
{
// perform a lexicographic sort on End, Start, IsDeletion
diff --git a/include/pacbio/consensus/Polish.h b/include/pacbio/consensus/Polish.h
index 5eedc1a..9a47e22 100644
--- a/include/pacbio/consensus/Polish.h
+++ b/include/pacbio/consensus/Polish.h
@@ -56,8 +56,14 @@ struct PolishConfig
PolishConfig(size_t iterations = 40, size_t separation = 10, size_t neighborhood = 20);
};
+/// Given an AbstractIntegrator and a PolishConfig,
+/// iteratively polish the template,
+/// and return meta information about the procedure.
+///
+/// The template will be polished within the AbstractIntegrator.
PolishResult Polish(AbstractIntegrator* ai, const PolishConfig& cfg);
+/// Struct that contains vectors for the base-wise individual and compound QVs.
struct QualityValues
{
std::vector<int> Qualities;
@@ -66,10 +72,14 @@ struct QualityValues
std::vector<int> SubstitutionQVs;
};
+/// Generates phred qualities of the current template.
std::vector<int> ConsensusQualities(AbstractIntegrator& ai);
+/// Generates individual and compound phred qualities of the current template.
QualityValues ConsensusQVs(AbstractIntegrator& ai);
+/// Returns a list of all possible mutations that can be applied to the template
+/// of the provided integrator.
std::vector<Mutation> Mutations(const AbstractIntegrator& ai);
} // namespace Consensus
diff --git a/include/pacbio/consensus/Template.h b/include/pacbio/consensus/Template.h
index f4b0b8c..1b013be 100644
--- a/include/pacbio/consensus/Template.h
+++ b/include/pacbio/consensus/Template.h
@@ -173,7 +173,7 @@ public:
AbstractRecursor(std::unique_ptr<AbstractTemplate>&& tpl, const PacBio::Data::MappedRead& mr,
double scoreDiff);
virtual ~AbstractRecursor() {}
- virtual size_t FillAlphaBeta(M& alpha, M& beta) const = 0;
+ virtual size_t FillAlphaBeta(M& alpha, M& beta, double tol) const = 0;
virtual void FillAlpha(const M& guide, M& alpha) const = 0;
virtual void FillBeta(const M& guide, M& beta) const = 0;
virtual double LinkAlphaBeta(const M& alpha, size_t alphaColumn, const M& beta,
diff --git a/src/Consensus.cpp b/include/pacbio/data/PlainOption.h
similarity index 67%
rename from src/Consensus.cpp
rename to include/pacbio/data/PlainOption.h
index a74e0f8..a0b26ee 100644
--- a/src/Consensus.cpp
+++ b/include/pacbio/data/PlainOption.h
@@ -33,29 +33,37 @@
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
-// Author: Lance Hepler
+// Author: Armin Töpfer
+#pragma once
-#include <limits>
+#include <string>
+#include <vector>
-#include <pacbio/ccs/Consensus.h>
+#include <pbcopper/cli/CLI.h>
namespace PacBio {
-namespace CCS {
-
-ConsensusSettings::ConsensusSettings(const optparse::Values& options)
- : MaxPoaCoverage{std::numeric_limits<size_t>::max()}
- , MaxLength{options.get(OptionNames::MaxLength)}
- , MinLength{options.get(OptionNames::MinLength)}
- , MinPasses{options.get(OptionNames::MinPasses)}
- , MinPredictedAccuracy{options.get(OptionNames::MinPredictedAccuracy)}
- , MinZScore{options.get(OptionNames::MinZScore)}
- , MaxDropFraction{options.get(OptionNames::MaxDropFraction)}
- , ByStrand{options.get(OptionNames::ByStrand)}
- , NoPolish{options.get(OptionNames::NoPolish)}
- , MinReadScore{static_cast<float>(options.get(OptionNames::MinReadScore))}
- , MinSNR{static_cast<double>(options.get(OptionNames::MinSnr))}
+namespace Data {
+struct PlainOption
{
-}
+ std::string id;
+ std::vector<std::string> cliOptions;
+ std::string name;
+ std::string description;
+ JSON::Json defaultValue;
-} // namespace CCS
-} // namespace PacBio
+ PlainOption(std::string id, std::vector<std::string> cliOptions, std::string name,
+ std::string description, JSON::Json defaultValue)
+ : id(id)
+ , cliOptions(cliOptions)
+ , name(name)
+ , description(description)
+ , defaultValue(defaultValue)
+ {
+ }
+
+ operator CLI::Option() const { return {id, cliOptions, description, defaultValue}; }
+ operator std::pair<std::string, std::string>() const { return std::make_pair(id, name); }
+ operator std::string() const { return id; }
+};
+}
+} // :: PacBio::CLI
\ No newline at end of file
diff --git a/include/pacbio/data/Read.h b/include/pacbio/data/Read.h
index 7cc5b70..05d45b8 100644
--- a/include/pacbio/data/Read.h
+++ b/include/pacbio/data/Read.h
@@ -46,6 +46,7 @@
namespace PacBio {
namespace Data {
+/// Stores nucleotide-wise signal to noise ratios.
struct SNR
{
double A;
@@ -75,6 +76,7 @@ struct SNR
SNR ClampSNR(const SNR& val, const SNR& min, const SNR& max);
+/// A Read contains the name, sequence, covariates, SNR, and associated model.
struct Read
{
Read(const std::string& name, const std::string& seq, const std::vector<uint8_t>& ipd,
@@ -92,6 +94,8 @@ struct Read
inline size_t Length() const { return Seq.length(); }
};
+/// A MappedRead extends Read by the strand information and template anchoring
+/// positions.
struct MappedRead : public Read
{
MappedRead(const Read& read, StrandType strand, size_t templateStart, size_t templateEnd,
diff --git a/include/pacbio/denovo/PoaGraph.h b/include/pacbio/denovo/PoaGraph.h
index 36a3751..d651d83 100644
--- a/include/pacbio/denovo/PoaGraph.h
+++ b/include/pacbio/denovo/PoaGraph.h
@@ -116,6 +116,8 @@ public:
void WriteGraphVizFile(const std::string& filename, int flags = 0,
const PoaConsensus* pc = NULL) const;
+ void WriteGraphCsvFile(const std::string& filename) const;
+
const PoaConsensus* FindConsensus(const PacBio::Align::AlignConfig& config,
int minCoverage = -INT_MAX) const;
diff --git a/include/pacbio/denovo/SparsePoa.h b/include/pacbio/denovo/SparsePoa.h
index 3ade174..fdc6371 100644
--- a/include/pacbio/denovo/SparsePoa.h
+++ b/include/pacbio/denovo/SparsePoa.h
@@ -140,6 +140,8 @@ public:
void WriteGraphVizFile(const std::string& filename, int flags = 0,
const PacBio::Poa::PoaConsensus* pc = nullptr) const;
+ void WriteGraphCsvFile(const std::string& filename) const;
+
//
// Clean up the POA graph, pruning minority paths, to speed up
// successive AddRead operations.
diff --git a/scripts/task_pbccs_ccs b/scripts/task_pbccs_ccs
deleted file mode 100755
index 7768e6f..0000000
--- a/scripts/task_pbccs_ccs
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env python
-
-# TODO replace this with native C++ implementation.
-
-"""
-Wrapper for 'ccs' executable to provide tool contract interface support (and
-incidentally, using DataSet XML as input). Note that this will *not* currently
-support chunking, since it access the individual .bam files en masse.
-"""
-
-import logging
-import re
-import os
-import sys
-
-from pbcommand.models import FileTypes, SymbolTypes, get_pbparser
-from pbcommand.models.report import Report, Attribute
-from pbcommand.cli import pbparser_runner
-from pbcommand.utils import setup_log
-from pbcommand.engine import run_cmd
-from pbcore.io import ConsensusReadSet, SubreadSet
-
-__version__ = "0.1"
-log = logging.getLogger(__name__)
-
-class Constants(object):
- TOOL_ID = "pbccs.tasks.ccs"
- TOOL_NAME = "ccs"
- DRIVER_EXE = "task_pbccs_ccs --resolved-tool-contract "
- CCS_EXE = os.environ.get("__PBTEST_CCS_EXE", "ccs")
- #
- MIN_SNR_ID = "pbccs.task_options.min_snr"
- MIN_SNR_DEFAULT = 3.75
- MIN_READ_SCORE_ID = "pbccs.task_options.min_read_score"
- MIN_READ_SCORE_DEFAULT = 0.65
- MAX_LENGTH_ID = "pbccs.task_options.max_length"
- MAX_LENGTH_DEFAULT = 7000
- MIN_LENGTH_ID = "pbccs.task_options.min_length"
- MIN_LENGTH_DEFAULT = 10
- MIN_PASSES_ID = "pbccs.task_options.min_passes"
- MIN_PASSES_DEFAULT = 3
- MIN_PREDICTED_ACCURACY_ID = "pbccs.task_options.min_predicted_accuracy"
- MIN_PREDICTED_ACCURACY_DEFAULT = 0.9
- MIN_ZSCORE_ID = "pbccs.task_options.min_zscore"
- MIN_ZSCORE_DEFAULT = -5
- MAX_DROP_FRAC_ID = "pbccs.task_options.max_drop_fraction"
- MAX_DROP_FRAC_DEFAULT = 0.34
- NO_POLISH_ID="pbccs.task_options.no_polish"
- NO_POLISH_DEFAULT=False
- BY_STRAND_ID="pbccs.task_options.by_strand"
- BY_STRAND_DEFAULT=False
- MODEL_PATH_ID="pbccs.task_options.model_path"
- MODEL_PATH_DEFAULT=""
- MODEL_SPEC_ID="pbccs.task_options.model_spec"
- MODEL_SPEC_DEFAULT=""
- #
- REPORT_FIELDS = {
- "CCS generated": "num_ccs_reads",
- "Below SNR threshold": "num_below_snr_threshold",
- "No usable subreads": "num_no_usable_subreads",
- "Insert size too long": "num_insert_size_too_long",
- "Insert size too small": "num_insert_size_too_small",
- "Not enough full passes": "num_not_enough_full_passes",
- "Too many unusable subreads": "num_too_many_unusable_subreads",
- "CCS did not converge": "num_not_converged",
- "CCS below minimum predicted accuracy": "num_below_min_accuracy",
- }
-
-
-def args_runner(args):
- raise NotImplementedError("Please call 'ccs' directly.")
-
-
-def resolved_tool_contract_runner(rtc):
- """
- Run the ccs binary from the resolved tool contract, and generate an XML
- dataset around the resulting .bam file.
- """
- subreads_file = rtc.task.input_files[0]
- # XXX checking to make sure we don't propagate nonsense
- barcode_sets = set()
- with SubreadSet(subreads_file) as ds_in:
- for ext_res in ds_in.externalResources:
- if ext_res.barcodes is not None:
- barcode_sets.add(ext_res.barcodes)
- if len(barcode_sets) > 1:
- raise RuntimeError("The input SubreadSet contains multiple distinct "+
- "BarcodeSets.")
- output_file = rtc.task.output_files[0]
- if output_file.endswith(".consensusreadset.xml"):
- output_file = re.sub(".consensusreadset.xml", ".bam", output_file)
- assert output_file.endswith(".bam")
- report_file = rtc.task.output_files[1]
- log.info("CCS_EXE = {e}".format(e=Constants.CCS_EXE))
- args = [
- Constants.CCS_EXE,
- "--pbi",
- "--force",
- "--logLevel=DEBUG",
- "--reportFile=%s" % report_file,
- "--numThreads=%d" % rtc.task.nproc,
- "--minSnr=%g" % rtc.task.options[Constants.MIN_SNR_ID],
- "--minReadScore=%g" % rtc.task.options[Constants.MIN_READ_SCORE_ID],
- "--maxLength=%d" % rtc.task.options[Constants.MAX_LENGTH_ID],
- "--minLength=%d" % rtc.task.options[Constants.MIN_LENGTH_ID],
- "--minPasses=%d" % rtc.task.options[Constants.MIN_PASSES_ID],
- "--minZScore=%g" % rtc.task.options[Constants.MIN_ZSCORE_ID],
- "--maxDropFraction=%g" % rtc.task.options[Constants.MAX_DROP_FRAC_ID],
- "--minPredictedAccuracy=%g" % \
- rtc.task.options[Constants.MIN_PREDICTED_ACCURACY_ID],
- "--noPolish" if rtc.task.options[Constants.NO_POLISH_ID] else "",
- "--byStrand" if rtc.task.options[Constants.BY_STRAND_ID] else "",
- ("--modelPath=%s" % rtc.task.options[Constants.MODEL_PATH_ID]) if \
- rtc.task.options[Constants.MODEL_PATH_ID] else "",
- ("--modelSpec=%s" % rtc.task.options[Constants.MODEL_SPEC_ID]) if \
- rtc.task.options[Constants.MODEL_SPEC_ID] else "",
- subreads_file,
- output_file
- ]
- log.info(" ".join(args))
- result = run_cmd(
- cmd=" ".join(args),
- stdout_fh=sys.stdout,
- stderr_fh=sys.stderr)
- if result.exit_code != 0:
- return result.exit_code
- assert os.path.isfile(output_file)
- ccs_ds = ConsensusReadSet(output_file, strict=True)
- if len(barcode_sets) == 1:
- for ext_res in ccs_ds.externalResources:
- ext_res.barcodes = list(barcode_sets)[0]
- ccs_ds.write(rtc.task.output_files[0])
- ccs_ds.close()
- return 0
-
-
-def get_parser():
- p = get_pbparser(
- tool_id=Constants.TOOL_ID,
- version=__version__,
- name=Constants.TOOL_NAME,
- description=__doc__,
- driver_exe=Constants.DRIVER_EXE,
- nproc=SymbolTypes.MAX_NPROC,
- default_level="INFO")
- p.add_input_file_type(FileTypes.DS_SUBREADS, "subread_set",
- "SubreadSet", "Subread DataSet or .bam file")
- p.add_output_file_type(FileTypes.DS_CCS, "bam_output",
- name="ConsensusReadSet",
- description="Output DataSet XML file",
- default_name="ccs")
- p.add_output_file_type(FileTypes.TXT, "ccs_summary_txt",
- name="CCS run summary",
- description="Text report summarizing run statistics",
- default_name="ccs_summary")
- p.add_float(Constants.MIN_SNR_ID, "minSnr",
- default=Constants.MIN_SNR_DEFAULT,
- name="Minimum SNR",
- description="Minimum SNR of input subreads")
- p.add_float(Constants.MIN_READ_SCORE_ID, "minReadScore",
- default=Constants.MIN_READ_SCORE_DEFAULT,
- name="Minimum Read Score",
- description="Minimum read score of input subreads")
- p.add_int(Constants.MAX_LENGTH_ID, "maxLength",
- default=Constants.MAX_LENGTH_DEFAULT,
- name="Maximum Subread Length",
- description="Maximum length of subreads to use for generating CCS")
- p.add_int(Constants.MIN_LENGTH_ID, "minLength",
- default=Constants.MIN_LENGTH_DEFAULT,
- name="Minimum Subread Length",
- description="Minimum length of subreads to use for generating CCS")
- p.add_int(Constants.MIN_PASSES_ID, "minPasses",
- default=Constants.MIN_PASSES_DEFAULT,
- name="Minimum Number of Passes",
- description="Minimum number of subreads required to generate CCS")
- p.add_float(Constants.MIN_PREDICTED_ACCURACY_ID, "minPredictedAccuracy",
- default=Constants.MIN_PREDICTED_ACCURACY_DEFAULT,
- name="Minimum Predicted Accuracy",
- description="Minimum predicted accuracy in [0, 1]")
- p.add_float(Constants.MIN_ZSCORE_ID, "minZScore",
- default=Constants.MIN_ZSCORE_DEFAULT,
- name="Minimum Z Score",
- description="Minimum Z score to use a subread")
- p.add_float(Constants.MAX_DROP_FRAC_ID, "maxDropFraction",
- default=Constants.MAX_DROP_FRAC_DEFAULT,
- name="Maximum Dropped Fraction",
- description="Maximum fraction of subreads that can be dropped before " +
- "giving up")
- p.add_boolean(Constants.NO_POLISH_ID, "noPolish",
- default=Constants.NO_POLISH_DEFAULT,
- name="No Polish CCS",
- description="Only output the initial template derived from the POA")
- p.add_boolean(Constants.BY_STRAND_ID, "byStrand",
- default=Constants.BY_STRAND_DEFAULT,
- name="By Strand CCS",
- description="For each ZMW, generate two CCS sequences, one for each strand")
- p.add_str(Constants.MODEL_PATH_ID, "modelPath",
- default=Constants.MODEL_PATH_DEFAULT,
- name="Model(s) Path",
- description="Path to model parameter file(s)")
- p.add_str(Constants.MODEL_SPEC_ID, "modelSpec",
- default=Constants.MODEL_SPEC_DEFAULT,
- name="Model Override",
- description="Override default model selection with a provided model specification")
- return p
-
-
-def main(argv=sys.argv):
- return pbparser_runner(
- argv=argv[1:],
- parser=get_parser(),
- args_runner_func=args_runner,
- contract_runner_func=resolved_tool_contract_runner,
- alog=log,
- setup_log_func=setup_log)
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/src/AbstractIntegrator.cpp b/src/AbstractIntegrator.cpp
index 00adf87..9a28404 100644
--- a/src/AbstractIntegrator.cpp
+++ b/src/AbstractIntegrator.cpp
@@ -199,5 +199,5 @@ Mutation AbstractIntegrator::ReverseComplement(const Mutation& mut) const
return Mutation(mut.Type, TemplateLength() - mut.End(), Complement(mut.Base));
}
-} // namespace Align
+} // namespace Consensus
} // namespace PacBio
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5113729..6231ddc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,6 +20,7 @@ set(UNY_INCLUDE_DIRS
${SEQAN_INCLUDE_DIRS}
${CPPOPTPARSE_IncludeDir}
${PacBioBAM_INCLUDE_DIRS}
+ ${pbcopper_INCLUDE_DIRS}
CACHE INTERNAL
"${PROJECT_NAME}: Include Directories"
FORCE
@@ -62,7 +63,7 @@ add_library(unanimity STATIC
ChainSeeds.cpp
ChemistryMapping.cpp
ChemistryTriple.cpp
- Consensus.cpp
+ ConsensusSettings.cpp
Interval.cpp
ReadId.cpp
SparsePoa.cpp
@@ -83,6 +84,7 @@ set(UNY_LIBRARIES
${ZLIB_LIBRARIES}
${HTSLIB_LIBRARIES}
${PacBioBAM_LIBRARIES}
+ ${pbcopper_LIBRARIES}
CACHE INTERNAL
"${PROJECT_NAME}: Libraries"
FORCE
diff --git a/src/ConsensusSettings.cpp b/src/ConsensusSettings.cpp
new file mode 100644
index 0000000..34244b5
--- /dev/null
+++ b/src/ConsensusSettings.cpp
@@ -0,0 +1,300 @@
+// Copyright (c) 2014-2015, Pacific Biosciences of California, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted (subject to the limitations in the
+// disclaimer below) provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * Neither the name of Pacific Biosciences nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+// GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC
+// BIOSCIENCES AND ITS CONTRIBUTORS "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 PACIFIC BIOSCIENCES OR ITS
+// CONTRIBUTORS 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.
+
+// Author: Armin Töpfer
+
+#include <pacbio/ccs/ConsensusSettings.h>
+
+namespace PacBio {
+namespace CCS {
+namespace OptionNames {
+using PlainOption = Data::PlainOption;
+// clang-format off
+const PlainOption MaxLength{
+ "max_length",
+ { "maxLength" },
+ "Maximum Subread Length",
+ "Maximum length of subreads to use for generating CCS.",
+ CLI::Option::IntType(7000)
+};
+const PlainOption MinLength{
+ "min_length",
+ { "minLength" },
+ "Minimum Subread Length",
+ "Minimum length of subreads to use for generating CCS.",
+ CLI::Option::IntType(10)
+};
+const PlainOption MinPasses{
+ "min_passes",
+ { "minPasses" },
+ "Minimum Number of Passes",
+ "Minimum number of subreads required to generate CCS.",
+ CLI::Option::IntType(3)
+};
+const PlainOption MinPredictedAccuracy{
+ "min_predicted_accuracy",
+ { "minPredictedAccuracy" },
+ "Minimum Predicted Accuracy",
+ "Minimum predicted accuracy in [0, 1].",
+ CLI::Option::FloatType(0.9)
+};
+const PlainOption MinZScore{
+ "min_zscore",
+ { "minZScore" },
+ "Minimum Z Score",
+ "Minimum z-score to use a subread. NaN disables this filter.",
+ CLI::Option::FloatType(-3.5)
+};
+const PlainOption MaxDropFraction{
+ "max_drop_fraction",
+ { "maxDropFraction" },
+ "Maximum Dropped Fraction",
+ "Maximum fraction of subreads that can be dropped before giving up.",
+ CLI::Option::FloatType(0.34)
+};
+const PlainOption NoPolish{
+ "no_polish",
+ { "noPolish" },
+ "No Polish CCS",
+ "Only output the initial template derived from the POA (faster, less accurate).",
+ CLI::Option::BoolType()
+};
+const PlainOption MinReadScore{
+ "min_read_score",
+ { "minReadScore" },
+ "Minimal Read Score",
+ "Minimum read score of input subreads.",
+ CLI::Option::FloatType(0.75)
+};
+const PlainOption MinSnr{
+ "min_snr",
+ { "minSnr" },
+ "Minimum SNR",
+ "Minimum SNR of input subreads.",
+ CLI::Option::FloatType(3.75)
+ // See https://github.com/PacificBiosciences/pbccs/issues/86 for a more
+ // detailed discussion of this default.)
+};
+const PlainOption ByStrand{
+ "by_strand",
+ { "byStrand" },
+ "By Strand CCS",
+ "Generate a consensus for each strand.",
+ CLI::Option::BoolType()
+};
+const PlainOption ForceOutput{
+ "force",
+ { "force" },
+ "Force overwrite output",
+ "Overwrite OUTPUT file if present.",
+ CLI::Option::BoolType()
+};
+const PlainOption Zmws{
+ "zmws",
+ { "zmws" },
+ "Whitelist ZMWs",
+ "Generate CCS for the provided comma-separated holenumber ranges only. Default = all",
+ CLI::Option::StringType("")
+};
+const PlainOption ReportFile{
+ "report_file",
+ { "reportFile" },
+ "Report File Output",
+ "Where to write the results report.",
+ CLI::Option::StringType("ccs_report.txt")
+};
+const PlainOption NumThreads{
+ "num_threads",
+ { "numThreads" },
+ "Number of Threads",
+ "Number of threads to use, 0 means autodetection.",
+ CLI::Option::IntType(0)
+};
+const PlainOption LogFile{
+ "log_file",
+ { "logFile" },
+ "Log to a File",
+ "Log to a file, instead of STDERR.",
+ CLI::Option::StringType("")
+};
+const PlainOption LogLevel{
+ "log_level",
+ { "logLevel" },
+ "Set Log Level",
+ "Set log level.",
+ CLI::Option::StringType("INFO")
+};
+const PlainOption RichQVs{
+ "rich_qvs",
+ { "richQVs" },
+ "Emit individual QVs",
+ "Emit dq, iq, and sq \"rich\" quality tracks.",
+ CLI::Option::BoolType()
+};
+const PlainOption ModelPath{
+ "model_path",
+ { "modelPath" },
+ "Model(s) Path",
+ "Path to a model file or directory containing model files.",
+ CLI::Option::StringType("")
+};
+const PlainOption ModelSpec{
+ "model_spec",
+ { "modelSpec" },
+ "Model Override",
+ "Name of chemistry or model to use, overriding default selection.",
+ CLI::Option::StringType("")
+};
+// clang-format on
+} // namespace OptionNames
+
+ConsensusSettings::ConsensusSettings(const PacBio::CLI::Results& options)
+ : ByStrand(options[OptionNames::ByStrand])
+ , ForceOutput(options[OptionNames::ForceOutput])
+ , LogFile(std::forward<std::string>(options[OptionNames::LogFile]))
+ , LogLevel(std::forward<std::string>(options[OptionNames::LogLevel]))
+ , MaxDropFraction(options[OptionNames::MaxDropFraction])
+ , MaxLength(options[OptionNames::MaxLength])
+ , MinLength(options[OptionNames::MinLength])
+ , MinPasses(options[OptionNames::MinPasses])
+ , MinPredictedAccuracy(options[OptionNames::MinPredictedAccuracy])
+ , MinReadScore(options[OptionNames::MinReadScore])
+ , MinSNR(options[OptionNames::MinSnr])
+
+ , MinZScore(options[OptionNames::MinZScore] == nullptr
+ ? NAN
+ : static_cast<float>(options[OptionNames::MinZScore]))
+ , ModelPath(std::forward<std::string>(options[OptionNames::ModelPath]))
+ , ModelSpec(std::forward<std::string>(options[OptionNames::ModelSpec]))
+ , NoPolish(options[OptionNames::NoPolish])
+ , NThreads(ThreadCount(options[OptionNames::NumThreads]))
+ , ReportFile(std::forward<std::string>(options[OptionNames::ReportFile]))
+ , RichQVs(options[OptionNames::RichQVs])
+ , WlSpec(std::forward<std::string>(options[OptionNames::Zmws]))
+{
+}
+
+size_t ConsensusSettings::ThreadCount(int n)
+{
+ const int m = std::thread::hardware_concurrency();
+
+ if (n < 1) return std::max(1, m + n);
+
+ return std::min(m, n);
+}
+
+PacBio::CLI::Interface ConsensusSettings::CreateCLI(const std::string& description,
+ const std::string& version)
+{
+ using Option = PacBio::CLI::Option;
+ PacBio::CLI::Interface i{"ccs", description, version};
+
+ i.AlternativeToolContractName("pbccs");
+
+ i.AddHelpOption(); // use built-in help output
+ i.AddVersionOption(); // use built-in version output
+
+ // clang-format off
+ i.AddPositionalArguments({
+ {"input", "Input file.", "INPUT"},
+ {"output", "Output file.", "OUTPUT"}
+ });
+
+ i.AddOptions(
+ {
+ OptionNames::ForceOutput,
+ OptionNames::Zmws,
+ OptionNames::MaxLength,
+ OptionNames::MinLength,
+ OptionNames::MinPasses,
+ OptionNames::MinPredictedAccuracy,
+ OptionNames::MinZScore,
+ OptionNames::MaxDropFraction,
+ OptionNames::MinSnr,
+ OptionNames::MinReadScore,
+ OptionNames::ByStrand,
+ OptionNames::NoPolish,
+ OptionNames::RichQVs,
+ OptionNames::ReportFile,
+ OptionNames::ModelPath,
+ OptionNames::ModelSpec,
+ OptionNames::NumThreads,
+ OptionNames::LogFile,
+ OptionNames::LogLevel
+ });
+
+ const std::string id = "pbccs.tasks.ccs";
+ CLI::ToolContract::Task tcTask(id);
+ tcTask.AddOption(OptionNames::MinSnr);
+ tcTask.AddOption(OptionNames::MinReadScore);
+ tcTask.AddOption(OptionNames::MaxLength);
+ tcTask.AddOption(OptionNames::MinLength);
+ tcTask.AddOption(OptionNames::MinPasses);
+ tcTask.AddOption(OptionNames::MinPredictedAccuracy);
+ tcTask.AddOption(OptionNames::MinZScore);
+ tcTask.AddOption(OptionNames::MaxDropFraction);
+ tcTask.AddOption(OptionNames::NoPolish);
+ tcTask.AddOption(OptionNames::ByStrand);
+ tcTask.AddOption(OptionNames::ModelPath);
+ tcTask.AddOption(OptionNames::ModelSpec);
+ tcTask.AddOption(OptionNames::ReportFile);
+
+ tcTask.InputFileTypes({
+ {
+ "subread_set",
+ "SubreadSet",
+ "Subread DataSet or .bam file",
+ "PacBio.DataSet.SubreadSet"
+ }
+ });
+
+ tcTask.OutputFileTypes({
+ {
+ "bam_output",
+ "ConsensusReadSet",
+ "Output DataSet XML file",
+ "PacBio.DataSet.ConsensusReadSet",
+ "ccs"
+ }
+ });
+
+ CLI::ToolContract::Config tcConfig(tcTask);
+ i.EnableToolContract(tcConfig);
+ // clang-format on
+
+ return i;
+}
+}
+} // ::PacBio::CCS
\ No newline at end of file
diff --git a/src/Evaluator.cpp b/src/Evaluator.cpp
index e7508ab..e258ee9 100644
--- a/src/Evaluator.cpp
+++ b/src/Evaluator.cpp
@@ -193,6 +193,24 @@ const AbstractMatrix& Evaluator::Beta() const
}
}
+const AbstractMatrix* Evaluator::AlphaView(MatrixViewConvention c) const
+{
+ if (IsValid()) {
+ return impl_->AlphaView(c);
+ } else {
+ return nullptr;
+ }
+}
+
+const AbstractMatrix* Evaluator::BetaView(MatrixViewConvention c) const
+{
+ if (IsValid()) {
+ return impl_->BetaView(c);
+ } else {
+ return nullptr;
+ }
+}
+
void Evaluator::CheckZScore(const double minZScore, const std::string& model)
{
// the zscore filter is disabled under the following conditions
diff --git a/src/EvaluatorImpl.cpp b/src/EvaluatorImpl.cpp
index 88f918b..4f4fefa 100644
--- a/src/EvaluatorImpl.cpp
+++ b/src/EvaluatorImpl.cpp
@@ -38,6 +38,7 @@
#include <boost/optional.hpp>
#include "EvaluatorImpl.h"
+#include "matrix/BasicDenseMatrix.h"
using namespace PacBio::Data;
@@ -45,6 +46,8 @@ namespace PacBio {
namespace Consensus {
namespace { // anonymous
+constexpr double ALPHA_BETA_MISMATCH_TOLERANCE = 0.001;
+constexpr double EARLY_ALPHA_BETA_MISMATCH_TOLERANCE = 0.0001;
constexpr size_t EXTEND_BUFFER_COLUMNS = 8;
#if 0
@@ -92,7 +95,7 @@ EvaluatorImpl::EvaluatorImpl(std::unique_ptr<AbstractTemplate>&& tpl, const Mapp
, beta_(mr.Length() + 1, recursor_->tpl_->Length() + 1, ScaledMatrix::REVERSE)
, extendBuffer_(mr.Length() + 1, EXTEND_BUFFER_COLUMNS, ScaledMatrix::FORWARD)
{
- numFlipFlops_ = recursor_->FillAlphaBeta(alpha_, beta_);
+ numFlipFlops_ = recursor_->FillAlphaBeta(alpha_, beta_, EARLY_ALPHA_BETA_MISMATCH_TOLERANCE);
}
std::string EvaluatorImpl::ReadName() const { return recursor_->read_.Name; }
@@ -215,7 +218,7 @@ inline void EvaluatorImpl::Recalculate()
alpha_.Reset(I, J);
beta_.Reset(I, J);
extendBuffer_.Reset(I, EXTEND_BUFFER_COLUMNS);
- recursor_->FillAlphaBeta(alpha_, beta_);
+ recursor_->FillAlphaBeta(alpha_, beta_, ALPHA_BETA_MISMATCH_TOLERANCE);
}
bool EvaluatorImpl::ApplyMutation(const Mutation& mut)
@@ -240,5 +243,53 @@ const AbstractMatrix& EvaluatorImpl::Alpha() const { return alpha_; }
const AbstractMatrix& EvaluatorImpl::Beta() const { return beta_; }
+const AbstractMatrix* EvaluatorImpl::AlphaView(MatrixViewConvention c) const
+{
+ BasicDenseMatrix* m = new BasicDenseMatrix(alpha_.Rows(), alpha_.Columns());
+
+ for (size_t i = 0; i < alpha_.Rows(); ++i) {
+ for (size_t j = 0; j < alpha_.Columns(); ++j) {
+ switch (c) {
+ case MatrixViewConvention::AS_IS:
+ (*m)(i, j) = alpha_(i, j);
+ break;
+ case MatrixViewConvention::LOGSPACE:
+ (*m)(i, j) = std::log(alpha_(i, j)) + alpha_.GetLogScale(j);
+ break;
+ case MatrixViewConvention::LOGPROBABILITY:
+ (*m)(i, j) = std::log(alpha_(i, j)) + alpha_.GetLogScale(j) +
+ recursor_->UndoCounterWeights(i);
+ break;
+ }
+ }
+ }
+
+ return m;
+}
+
+const AbstractMatrix* EvaluatorImpl::BetaView(MatrixViewConvention c) const
+{
+ BasicDenseMatrix* m = new BasicDenseMatrix(beta_.Rows(), beta_.Columns());
+
+ for (size_t i = 0; i < beta_.Rows(); ++i) {
+ for (size_t j = 0; j < beta_.Columns(); ++j) {
+ switch (c) {
+ case MatrixViewConvention::AS_IS:
+ (*m)(i, j) = beta_(i, j);
+ break;
+ case MatrixViewConvention::LOGSPACE:
+ (*m)(i, j) = std::log(beta_(i, j)) + beta_.GetLogScale(j);
+ break;
+ case MatrixViewConvention::LOGPROBABILITY:
+ (*m)(i, j) = std::log(beta_(i, j)) + beta_.GetLogScale(j) +
+ recursor_->UndoCounterWeights(beta_.Rows() - 1 - i);
+ break;
+ }
+ }
+ }
+
+ return m;
+}
+
} // namespace Consensus
} // namespace PacBio
diff --git a/src/EvaluatorImpl.h b/src/EvaluatorImpl.h
index 28524d8..abdaa0c 100644
--- a/src/EvaluatorImpl.h
+++ b/src/EvaluatorImpl.h
@@ -40,6 +40,7 @@
#include <vector>
#include <pacbio/consensus/Evaluator.h>
+#include <pacbio/consensus/MatrixViewConvention.h>
#include <pacbio/consensus/Template.h>
#include <pacbio/data/Read.h>
@@ -74,6 +75,10 @@ public:
const AbstractMatrix& Alpha() const;
const AbstractMatrix& Beta() const;
+public:
+ const AbstractMatrix* AlphaView(MatrixViewConvention c) const;
+ const AbstractMatrix* BetaView(MatrixViewConvention c) const;
+
private:
void Recalculate();
diff --git a/src/ModelSelection.cpp b/src/ModelSelection.cpp
index 660bf19..77c6951 100644
--- a/src/ModelSelection.cpp
+++ b/src/ModelSelection.cpp
@@ -96,11 +96,12 @@ size_t LoadModelsFromDirectory(const std::string& dirPath)
// iterate through .json files in directory,
// loading any into ModelFactory
bool ret = true;
- size_t nModels = 0;
+ size_t nModels = 0, dot;
struct dirent* ep;
while ((ep = readdir(dp)) != nullptr) {
std::string path = dirPath + '/' + ep->d_name;
- if (path.substr(path.find_last_of('.')) != ".json") continue;
+ if ((dot = path.find_last_of('.')) == std::string::npos || path.substr(dot) != ".json")
+ continue;
if (!(ret &= (stat(path.c_str(), &st) == 0))) break;
if (S_ISREG(st.st_mode)) {
if ((ret &= LoadModelFromFile(path)))
diff --git a/src/Read.cpp b/src/Read.cpp
index 882eaf0..6284a9f 100644
--- a/src/Read.cpp
+++ b/src/Read.cpp
@@ -64,6 +64,10 @@ Read::Read(const std::string& name, const std::string& seq, const std::vector<ui
const std::vector<uint8_t>& pw, const SNR& snr, const std::string& model)
: Name{name}, Seq{seq}, IPD{ipd}, PulseWidth{pw}, SignalToNoise{snr}, Model{model}
{
+ if (ipd.size() != seq.size() || pw.size() != seq.size()) {
+ throw new std::invalid_argument("Invalid Read (name=" + name +
+ "): features IPD/PW/seq are of mismatched length");
+ }
}
MappedRead::MappedRead(const Read& read, StrandType strand, size_t templateStart,
@@ -98,5 +102,5 @@ std::ostream& operator<<(std::ostream& os, const MappedRead& mr)
return os;
}
-} // namespace Consensus
+} // namespace Data
} // namespace PacBio
diff --git a/src/Recursor.h b/src/Recursor.h
index 9932151..7d5480a 100644
--- a/src/Recursor.h
+++ b/src/Recursor.h
@@ -54,72 +54,89 @@ namespace Consensus {
// AbstractRecursor is in Template.h
// TODO(lhepler) comment about use of CRTP
+
+/// The recursor is the heart of ConsensusCore. Via dynamic programming,
+/// it computes the log probability that the MappedRead stems from the Template.
+///
+/// In a traditional fashion the forward matrix is being computed and instead of
+/// takin the Viterbi path, the backward matrix is computed.
+/// Both combined provide the posterior probabilities that the optimal path goes
+/// through this cell.
+///
+/// The trick is, after each mutation, only the affected column itself and its
+/// neighbors need to be recomputed. This allows a rapid exploration of the
+/// likelihood surface to find the next best mutations to generate a template
+/// that is more likely to generate the observed MappedRead.
template <typename Derived>
class Recursor : public AbstractRecursor
{
public:
- // \brief Construct a Recursor from a Template and a MappedRead,
- // The scoreDiff here is passed in negative logScale and converted
- // to the appropriate divisor.
+ /// \brief Construct a Recursor from a Template and a MappedRead.
+ /// The scoreDiff here is passed in negative logScale and converted
+ /// to the appropriate divisor.
Recursor(std::unique_ptr<AbstractTemplate>&& tpl, const PacBio::Data::MappedRead& mr,
double scoreDiff = 12.5);
/// \brief Fill the alpha and beta matrices.
+ ///
/// This routine will fill the alpha and beta matrices, ensuring
/// that the score computed from the alpha and beta recursions are
/// identical, refilling back-and-forth if necessary.
- size_t FillAlphaBeta(M& alpha, M& beta) const;
-
- /**
- Fill in the alpha matrix. This matrix has the read run along the rows, and
- the template run along the columns. The first row and column do not correspond
- to a template position. Therefore the match represented at position (i,j)
- corresponds to a match between template positions (i+1, j+1).
-
- The alpha matrix is the "Forward" matrix used in the forward/backward
- algorithm.
- The i,j position of the matrix represents the probability of all paths up
- to the point where the ith read position and jth template have been
- "emitted."
- The matrix is calculated recursively by examining all possible transitions
- into (i,j), and calculating the probability we were in the previous state,
- times the probability of a transition into (i,j) times the probability of
- emitting the observation that corresponds to (i,j). All probabilities are
- calculated and stored as LOG values.
-
- Note that in doing this calculation, in order to work with di-nucleotide
- contexts, we require that the first and last transition be a match. In other words the
- start and end of the read and template are "pinned" to each other.
-
- //TODO: Verify memory is initialized to 0!
-
- @param guide An object that helps inform how to select the size of "bands"
- for the banded algorithm used. This is typically the beta matrix if we are
- "repopulating" the matrix.
- @param alpha The matrix to be filled.
- */
-
+ ///
+ /// Returns the number of flip flop events (refilling events).
+ size_t FillAlphaBeta(M& alpha, M& beta, double tol) const;
+
+ /// \brief Fill in the alpha matrix.
+ ///
+ /// This matrix has the read run along the rows and the template run along
+ /// the columns. The first row and column do not correspond to a template
+ /// position. Therefore the match represented at position (i,j) corresponds
+ /// to a match between template positions (i+1, j+1).
+ ///
+ /// The alpha matrix is the "Forward" matrix used in the forward/backward
+ /// algorithm.
+ ///
+ /// The (i,j) position of the matrix represents the probability of all paths
+ /// up to the point where the i-th read position and j-th template have been
+ /// "emitted."
+ ///
+ /// The matrix is calculated recursively by examining all possible
+ /// transitions into (i,j), and calculating the probability we were in the
+ /// previous state, times the probability of a transition into (i,j) times
+ /// the probability of emitting the observation that corresponds to (i,j).
+ /// All probabilities are calculated and stored as LOG values.
+ ///
+ /// Note that in doing this calculation, in order to work with di-nucleotide
+ /// contexts, we require that the first and last transition be a match.
+ /// In other words the start and end of the read and template are "pinned"
+ /// to each other.
+ ///
+ /// TODO: Verify memory is initialized to 0!
+ ///
+ /// \param guide An object that helps inform how to select the size of
+ /// "bands" for the banded algorithm used. This is typically
+ /// the beta matrix if we are "repopulating" the matrix.
+ /// \param alpha The matrix to be filled.
void FillAlpha(const M& guide, M& alpha) const;
- /**
- Fill the Beta matrix, the backwards half of the forward-backward algorithm.
- This represents the probability that starting from the (i,j) state, the
- combined probability of transitioning out and following all paths through to the
- end. That is, we need to calculate transition from state and emit from next
- state for each
-
- In combination with the Alpha matrix, this allows us to calculate all paths
- that pass through the (i,j) element, as exp(Alpha(i,j) + Beta(i,j))
-
- All probabilities stored in the matrix are stored as NON-LOGGED
- probabilities.
-
- @param e The evaluator, such as QvEvaluator
- @param M the guide matrix for banding (this needs more documentation)
- @param beta The Beta matrix, stored as either a DenseMatrix or a
- SparseMatrix.
- */
-
+ /// \brief Fill the Beta matrix.
+ /// That is the backwards half of the forward-backward algorithm.
+ /// This represents the probability that starting from the (i,j) state, the
+ /// combined probability of transitioning out and following all paths
+ /// through to the end. That is, we need to calculate transition from state
+ /// and emit from next state for each
+ ///
+ /// In combination with the Alpha matrix, this allows us to calculate all
+ /// paths that pass through the (i,j) element,
+ /// as exp(Alpha(i,j) + Beta(i,j))
+ ///
+ /// All probabilities stored in the matrix are stored as NON-LOGGED
+ /// probabilities.
+ ///
+ /// \param e The evaluator, such as QvEvaluator
+ /// \param M the guide matrix for banding (this needs more documentation)
+ /// \param beta The Beta matrix, stored as either a DenseMatrix or a
+ /// SparseMatrix.
void FillBeta(const M& guide, M& beta) const;
/// \brief Calculate the recursion score by "linking" partial alpha and/or
@@ -127,8 +144,21 @@ public:
double LinkAlphaBeta(const M& alpha, size_t alphaColumn, const M& beta, size_t betaColumn,
size_t absoluteColumn) const;
+ /// This method extends the Alpha matrix into a temporary matrix given by
+ /// ext. It extends the region [beginColumn, beginColumn + numExtColumns)
+ ///
+ /// \param alpha The alpha matrix
+ /// \param beginColumn The column where extension should start
+ /// \param ext The matrix to be extended
+ /// \param numExtColumns The number of columns to be extended
void ExtendAlpha(const M& alpha, size_t beginColumn, M& ext, size_t numExtColumns = 2) const;
+ /// This method extends the Beta matrix into a temporary matrix given by ext.
+ ///
+ /// \param beta The beta matrix
+ /// \param endColumn The right-hand side where extension should start
+ /// \param ext The matrix to be extended
+ /// \param lengthDiff The length difference of the mutation
void ExtendBeta(const M& beta, size_t endColumn, M& ext, int lengthDiff = 0) const;
private:
@@ -139,7 +169,6 @@ private:
/// of the maximum path through each and the inputs for column j.
bool RangeGuide(size_t j, const M& guide, const M& matrix, size_t* beginRow,
size_t* endRow) const;
- // The RangeGuide function determines the minimum score by dividing out scoreDiff_
private:
std::vector<uint8_t> emissions_;
@@ -152,7 +181,6 @@ typedef std::pair<size_t, size_t> Interval;
// TODO(dalexander): put these into a RecursorConfig struct
// TODO(anybody): Hmmm... not sure what the heck to do about these...
constexpr int MAX_FLIP_FLOPS = 5;
-constexpr double ALPHA_BETA_MISMATCH_TOLERANCE = 0.001;
constexpr double REBANDING_THRESHOLD = 0.04;
constexpr uint8_t kDefaultBase = 0; // corresponding to A, usually
@@ -456,19 +484,13 @@ double Recursor<Derived>::LinkAlphaBeta(const M& alpha, size_t alphaColumn, cons
beta.GetLogProdScales(betaColumn, beta.Columns()));
}
-/**
- This method extends that Alpha matrix into a temporary matrix given by
- ext. It extends the region [beginColumn, beginColumn + numExtColumns)
-
- Note that this method is used EXCLUSIVELY for testing mutations, and so
- we don't get the actual parameters and positions from the template, but we
- get them after a "virtual" mutation has been applied.
-
- All new data is placed in the extension matrix. The guesses for start/end
- rows in the banding are determined by evaluating neighbors of each position.
- @param <#parameter#>
- @returns <#retval#>
- */
+/// Note that this method is used EXCLUSIVELY for testing mutations, and so
+/// we don't get the actual parameters and positions from the template, but
+/// we get them after a "virtual" mutation has been applied.
+///
+/// All new data is placed in the extension matrix. The guesses for
+/// start/end rows in the banding are determined by evaluating neighbors of
+/// each position.
template <typename Derived>
void Recursor<Derived>::ExtendAlpha(const M& alpha, size_t beginColumn, M& ext,
size_t numExtColumns) const
@@ -564,25 +586,23 @@ void Recursor<Derived>::ExtendAlpha(const M& alpha, size_t beginColumn, M& ext,
}
}
-// Semantic: After ExtendBeta(B, j), we have
-// ext(:, numExtColumns-1) = B'(:,j)
-// ext(:, numExtColumns-2) = B'(:,j-1) ...
-//
-// Note: lastColumn is the numerically largest column number that
-// will be filled, but it is filled first since beta fill is done
-// backwards.
-//
-// Accesses B(:, ..(j+2))
-
-/* Note this is a very confusing routine in order to avoid recomputing and
- additional memory allocations. This routine tries to stick on a beta matrix
- to the original and back trace to the 0,0 position of this extension matrix.
- matrix from the original. Note that the original beta
- matrix is indexed by the original template positions, while the template
- bases and parameters are now indexed according the the "virtual" template
- to which mutations have been applied.
- */
-// @param lastColumn - Where we
+/// Semantic: After ExtendBeta(B, j), we have
+/// ext(:, numExtColumns-1) = B'(:,j)
+/// ext(:, numExtColumns-2) = B'(:,j-1) ...
+///
+/// Note: lastColumn is the numerically largest column number that
+/// will be filled, but it is filled first since beta fill is done
+/// backwards.
+///
+/// Accesses B(:, ..(j+2))
+///
+/// Note this is a very confusing routine in order to avoid recomputing and
+/// additional memory allocations. This routine tries to stick on a beta matrix
+/// to the original and back trace to the 0,0 position of this extension matrix.
+/// matrix from the original. Note that the original beta
+/// matrix is indexed by the original template positions, while the template
+/// bases and parameters are now indexed according the the "virtual" template
+/// to which mutations have been applied.
template <typename Derived>
void Recursor<Derived>::ExtendBeta(const M& beta, size_t lastColumn, M& ext, int lengthDiff) const
{
@@ -697,7 +717,7 @@ Recursor<Derived>::Recursor(std::unique_ptr<AbstractTemplate>&& tpl,
}
template <typename Derived>
-size_t Recursor<Derived>::FillAlphaBeta(M& a, M& b) const
+size_t Recursor<Derived>::FillAlphaBeta(M& a, M& b, const double tol) const
{
if (tpl_->Length() == 0) throw std::runtime_error("template length is 0, invalid state!");
@@ -725,7 +745,7 @@ size_t Recursor<Derived>::FillAlphaBeta(M& a, M& b) const
alphaV = std::log(a(I, J)) + a.GetLogProdScales() + unweight;
betaV = std::log(b(0, 0)) + b.GetLogProdScales() + unweight;
- if (std::abs(1.0 - alphaV / betaV) <= ALPHA_BETA_MISMATCH_TOLERANCE) break;
+ if (std::abs(1.0 - alphaV / betaV) <= tol) break;
if (flipflops % 2 == 0)
FillAlpha(b, a);
@@ -735,7 +755,7 @@ size_t Recursor<Derived>::FillAlphaBeta(M& a, M& b) const
++flipflops;
}
- if (std::abs(1.0 - alphaV / betaV) > ALPHA_BETA_MISMATCH_TOLERANCE || !std::isfinite(betaV))
+ if (std::abs(1.0 - alphaV / betaV) > tol || !std::isfinite(betaV))
throw PacBio::Exception::AlphaBetaMismatch();
return flipflops;
@@ -772,6 +792,7 @@ inline Interval Recursor<Derived>::RowRange(size_t j, const M& matrix) const
return Interval(beginRow, endRow);
}
+// The RangeGuide function determines the minimum score by dividing out scoreDiff_.
template <typename Derived>
inline bool Recursor<Derived>::RangeGuide(size_t j, const M& guide, const M& matrix,
size_t* beginRow, size_t* endRow) const
diff --git a/src/Sequence.cpp b/src/Sequence.cpp
index 09a53df..4c5071e 100644
--- a/src/Sequence.cpp
+++ b/src/Sequence.cpp
@@ -94,5 +94,5 @@ std::string ReverseComplement(const std::string& input)
return output;
}
-} // namespace Consensus
+} // namespace Data
} // namespace PacBio
diff --git a/src/SparsePoa.cpp b/src/SparsePoa.cpp
index 10067c5..189944e 100644
--- a/src/SparsePoa.cpp
+++ b/src/SparsePoa.cpp
@@ -215,6 +215,11 @@ void SparsePoa::WriteGraphVizFile(const std::string& filename, int flags,
graph_->WriteGraphVizFile(filename, flags, pc);
}
+void SparsePoa::WriteGraphCsvFile(const std::string& filename) const
+{
+ graph_->WriteGraphCsvFile(filename);
+}
+
void SparsePoa::PruneGraph(float /* minCoverageFraction */) {}
void SparsePoa::repCheck()
{
@@ -222,5 +227,5 @@ void SparsePoa::repCheck()
assert(graph_->NumReads() == reverseComplemented_.size());
}
-} // namespace CCS
+} // namespace Poa
} // namespace PacBio
diff --git a/src/Timer.cpp b/src/Timer.cpp
index f43ca94..f4e2d06 100644
--- a/src/Timer.cpp
+++ b/src/Timer.cpp
@@ -57,5 +57,5 @@ float Timer::ElapsedSeconds() const { return ElapsedMilliseconds() / 1000; }
void Timer::Restart() { tick = steady_clock::now(); }
-} // namespace CCS
+} // namespace Util
} // namespace PacBio
diff --git a/src/Utility.cpp b/src/Utility.cpp
index b409aa1..f969ec8 100644
--- a/src/Utility.cpp
+++ b/src/Utility.cpp
@@ -71,6 +71,9 @@ bool FileExists(const string& path)
string FileExtension(const string& path)
{
+ auto pathLower = path;
+ std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), ::tolower);
+
size_t fileStart = path.find_last_of("/");
if (fileStart == string::npos) fileStart = 0;
@@ -133,5 +136,5 @@ bool ValidBaseFeatures(const PacBio::BAM::DataSet& ds)
return true;
}
-} // namespace CCS
+} // namespace IO
} // namespace PacBio
diff --git a/src/align/AlignConfig.cpp b/src/align/AlignConfig.cpp
index 7f24eeb..c6ee5cb 100644
--- a/src/align/AlignConfig.cpp
+++ b/src/align/AlignConfig.cpp
@@ -54,5 +54,5 @@ AlignConfig AlignConfig::Default()
return AlignConfig(AlignParams::Default(), AlignMode::GLOBAL);
}
-} // namespace Consensus
+} // namespace Align
} // namespace PacBio
diff --git a/src/main/ccs.cpp b/src/main/ccs.cpp
index 17114d7..7d76dee 100644
--- a/src/main/ccs.cpp
+++ b/src/main/ccs.cpp
@@ -46,11 +46,13 @@
#include <string>
#include <vector>
+#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/replace.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/optional.hpp>
-#include <OptionParser.h>
+#include <pbcopper/cli/CLI.h>
#include <pbbam/BamWriter.h>
#include <pbbam/EntireFileQuery.h>
@@ -85,27 +87,10 @@ using namespace PacBio::Logging;
using boost::none;
using boost::numeric_cast;
using boost::optional;
-using optparse::OptionParser;
// these strings are part of the BAM header, they CANNOT contain newlines
-#define DESCRIPTION "Generate circular consensus sequences (ccs) from subreads."
-
-namespace PacBio {
-namespace CCS {
-namespace OptionNames {
-constexpr auto ForceOutput = "force";
-constexpr auto PbIndex = "pbi";
-constexpr auto Zmws = "zmws";
-constexpr auto ReportFile = "reportFile";
-constexpr auto NumThreads = "numThreads";
-constexpr auto LogFile = "logFile";
-constexpr auto LogLevel = "logLevel";
-constexpr auto RichQVs = "richQVs";
-constexpr auto ModelPath = "modelPath";
-constexpr auto ModelSpec = "modelSpec";
-} // namespace OptionNames
-} // namespace CCS
-} // namespace PacBio
+const std::string DESCRIPTION = "Generate circular consensus sequences (ccs) from subreads.";
+const std::string APPNAME = "ccs";
typedef ReadType<ReadId> Subread;
typedef ChunkType<ReadId, Subread> Chunk;
@@ -251,13 +236,13 @@ Results FastqWriterThread(WorkQueue<Results>& queue, const string& fname)
return counts;
}
-BamHeader PrepareHeader(const OptionParser& parser, int argc, char** argv, const DataSet& ds)
+BamHeader PrepareHeader(const std::string& cmdLine, const DataSet& ds)
{
using boost::algorithm::join;
- ProgramInfo program(parser.prog() + "-" + PacBio::UnanimityVersion());
- program.Name(parser.prog())
- .CommandLine(parser.prog() + " " + join(vector<string>(argv + 1, argv + argc), " "))
+ ProgramInfo program(APPNAME + "-" + PacBio::UnanimityVersion());
+ program.Name(APPNAME)
+ .CommandLine(APPNAME + " " + cmdLine)
.Description(DESCRIPTION)
.Version(PacBio::UnanimityVersion());
@@ -267,7 +252,7 @@ BamHeader PrepareHeader(const OptionParser& parser, int argc, char** argv, const
for (const auto& bam : ds.BamFiles()) {
for (const auto& rg : bam.Header().ReadGroups()) {
if (rg.ReadType() != "SUBREAD")
- parser.error("invalid input file, READTYPE must be SUBREAD");
+ std::cerr << "invalid input file, READTYPE must be SUBREAD" << std::endl;
ReadGroupInfo readGroup(rg.MovieName(), "CCS");
readGroup.BindingKit(rg.BindingKit())
@@ -287,15 +272,6 @@ BamHeader PrepareHeader(const OptionParser& parser, int argc, char** argv, const
return header;
}
-size_t ThreadCount(int n)
-{
- const int m = thread::hardware_concurrency();
-
- if (n < 1) return max(1, m + n);
-
- return min(m, n);
-}
-
void WriteResultsReport(ostream& report, const Results& counts)
{
size_t total = counts.Total();
@@ -339,117 +315,57 @@ void WriteResultsReport(ostream& report, const Results& counts)
counts.SubreadCounter.WriteResultsReport(report);
}
-int main(int argc, char** argv)
+static int Runner(const PacBio::CLI::Results& args)
{
using boost::algorithm::join;
using boost::make_optional;
SetColumns();
- // args and options
- //
- //
- // clang-format off
- // clang messes with the way the arg to version() is formatted..
- auto parser =
- OptionParser()
- .usage("usage: %prog [OPTIONS] INPUT OUTPUT")
- .version("%prog " + PacBio::UnanimityVersion() + " (commit " + PacBio::UnanimityGitSha1() + ")" +
- "\nunanimity " + PacBio::UnanimityVersion() + " (commit " + PacBio::UnanimityGitSha1() + ")" +
- "\nCopyright (c) 2014-2016 Pacific Biosciences, Inc.\nLicense: 3-BSD")
- .description(DESCRIPTION
- "\nAdditional documentation: http://github.com/PacificBiosciences/unanimity");
- // clang-format on
- //
- const vector<string> logLevels = {"TRACE", "DEBUG", "INFO", "NOTICE",
- "WARN", "ERROR", "CRITICAL", "FATAL"};
- const string em = "--";
-
- parser.add_option(em + OptionNames::ForceOutput)
- .action("store_true")
- .help("Overwrite OUTPUT file if present.");
- parser.add_option(em + OptionNames::PbIndex)
- .action("store_true")
- .help("Generate a .pbi file for the OUTPUT file.");
- parser.add_option(em + OptionNames::Zmws)
- .help(
- "Generate CCS for the provided comma-separated holenumber ranges only. Default = all");
-
- ConsensusSettings::AddOptions(&parser);
-
- parser.add_option(em + OptionNames::RichQVs)
- .action("store_true")
- .help("Emit dq, iq, and sq \"rich\" quality tracks. Default = false");
- parser.add_option(em + OptionNames::ReportFile)
- .set_default("ccs_report.txt")
- .help("Where to write the results report. Default = %default");
- parser.add_option("-M", em + OptionNames::ModelPath)
- .help("Path to a model file or directory containing model files. Default = none");
- parser.add_option("-m", em + OptionNames::ModelSpec)
- .help("Name of chemistry or model to use, overriding default selection. Default = none");
- parser.add_option(em + OptionNames::NumThreads)
- .type("int")
- .set_default(0)
- .help("Number of threads to use, 0 means autodetection. Default = %default");
- parser.add_option(em + OptionNames::LogFile).help("Log to a file, instead of STDERR.");
- parser.add_option(em + OptionNames::LogLevel)
- .choices(logLevels.begin(), logLevels.end())
- .set_default("INFO")
- .help("Set log level. Default = %default");
-
- const auto options = parser.parse_args(argc, argv);
- const auto files = parser.args();
-
- const ConsensusSettings settings(options);
-
- const bool richQVs = options.get(OptionNames::RichQVs);
- const bool forceOutput = options.get(OptionNames::ForceOutput);
- const bool pbIndex = options.get(OptionNames::PbIndex);
- const size_t nThreads = ThreadCount(options.get(OptionNames::NumThreads));
- const size_t chunkSize = 1;
+ // Get source args
+ const std::vector<std::string> files = args.PositionalArguments();
+
+ // input validation
+ if (files.size() != 2) {
+ std::cerr << "ERROR: Please provide the INPUT and OUTPUT files.\n"
+ << " See --help for more info about positional arguments." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ const string inputFile = files.front();
+ string outputFile = files.back();
+
+ const ConsensusSettings settings(args);
// handle --zmws
//
//
optional<Whitelist> whitelist(none);
- const string wlspec(options.get(OptionNames::Zmws));
+ const std::string& wlSpec = settings.WlSpec;
try {
- if (!wlspec.empty()) whitelist = Whitelist(wlspec);
+ if (!wlSpec.empty()) whitelist = Whitelist(wlSpec);
} catch (...) {
- parser.error("option --zmws: invalid specification: '" + wlspec + "'");
+ std::cerr << "option --zmws: invalid specification: '" + wlSpec + "'" << std::endl;
}
- // input validation
- //
- //
- if (files.size() < 1)
- parser.error("missing INPUT and OUTPUT");
- else if (files.size() < 2)
- parser.error("missing OUTPUT");
- else if (files.size() > 2)
- parser.error("too many arguments for INPUT and OUTPUT");
-
- // pop first file off the list, is OUTPUT file
- const string inputFile = files.front();
- const string outputFile = files.back();
-
// verify input file exists
- if (!FileExists(inputFile)) parser.error("INPUT: file does not exist: '" + inputFile + "'");
+ if (!FileExists(inputFile))
+ std::cerr << "INPUT: file does not exist: '" + inputFile + "'" << std::endl;
// verify output file does not already exist
- if (FileExists(outputFile) && !forceOutput)
- parser.error("OUTPUT: file already exists: '" + outputFile + "'");
+ if (FileExists(outputFile) && !settings.ForceOutput)
+ std::cerr << "OUTPUT: file already exists: '" + outputFile + "'" << std::endl;
if (settings.ByStrand && settings.NoPolish)
- parser.error("option --byStrand: incompatible with --noPolish");
+ std::cerr << "option --byStrand: incompatible with --noPolish" << std::endl;
// logging
//
//
ofstream logStream;
{
- string logLevel(options.get(OptionNames::LogLevel));
- string logFile(options.get(OptionNames::LogFile));
+ const std::string& logLevel = settings.LogLevel;
+ const std::string& logFile = settings.LogFile;
if (!logFile.empty()) {
logStream.open(logFile);
@@ -464,7 +380,7 @@ int main(int argc, char** argv)
//
//
{
- string modelPath(options.get(OptionNames::ModelPath));
+ const std::string& modelPath = settings.ModelPath;
if (!modelPath.empty()) {
PBLOG_INFO << "Loading model parameters from: '" << modelPath << "'";
if (!LoadModels(modelPath)) {
@@ -486,7 +402,7 @@ int main(int argc, char** argv)
// test that all input chemistries are supported
{
set<string> used;
- string modelSpec(options.get(OptionNames::ModelSpec));
+ const std::string& modelSpec = settings.ModelSpec;
if (!modelSpec.empty()) {
PBLOG_INFO << "Overriding model selection with: '" << modelSpec << "'";
if (!(OverrideModel(modelSpec) && used.insert(modelSpec).second)) {
@@ -527,43 +443,52 @@ int main(int argc, char** argv)
else
query.reset(new PbiFilterQuery(filter, ds));
- WorkQueue<Results> workQueue(nThreads);
+ WorkQueue<Results> workQueue(settings.NThreads);
future<Results> writer;
+ // Check if output type is a dataset
const string outputExt = FileExtension(outputFile);
- if (outputExt == "bam") {
+ bool isXml = outputExt == "xml";
+ bool isBam = isXml || outputExt == "bam";
+
+ if (isXml) boost::ireplace_all(outputFile, ".consensusreadset.xml", ".bam");
+
+ if (isBam) {
unique_ptr<BamWriter> ccsBam(
- new BamWriter(outputFile, PrepareHeader(parser, argc, argv, ds)));
+ new BamWriter(outputFile, PrepareHeader(args.InputCommandLine(), ds)));
const std::string pbiFileName = outputFile + ".pbi";
- unique_ptr<PbiBuilder> ccsPbi(pbIndex ? new PbiBuilder(pbiFileName) : nullptr);
+ unique_ptr<PbiBuilder> ccsPbi(settings.PbIndex ? new PbiBuilder(pbiFileName) : nullptr);
writer = async(launch::async, BamWriterThread, ref(workQueue), move(ccsBam), move(ccsPbi),
- richQVs);
-
- // Prepare dataset
- const std::string desc =
- "Points to the ccs bam file generated by pbccs " + PacBio::UnanimityVersion();
- const std::string name = "ccs bam";
- const std::string metatype = "PacBio.DataSet.ConsensusReadSet";
- DataSet ccsSet(DataSet::TypeEnum::CONSENSUS_READ);
- ExternalResource resource(metatype, outputFile);
- resource.Name(name).Description(desc);
-
- if (pbIndex) {
- FileIndex pbi("PacBio.Index.PacBioIndex", pbiFileName);
+ settings.RichQVs);
+
+ // Always generate pbi file
+ FileIndex pbi("PacBio.Index.PacBioIndex", pbiFileName);
+
+ if (isXml) {
+ // Prepare dataset
+ const std::string desc =
+ "Points to the ccs bam file generated by pbccs " + PacBio::UnanimityVersion();
+ const std::string name = "ccs bam";
+ const std::string metatype = "PacBio.DataSet.ConsensusReadSet";
+ DataSet ccsSet(DataSet::TypeEnum::CONSENSUS_READ);
+ ExternalResource resource(metatype, outputFile);
+ resource.Name(name).Description(desc);
+
resource.FileIndices().Add(pbi);
- }
- ccsSet.ExternalResources().Add(resource);
+ ccsSet.ExternalResources().Add(resource);
- // File path without .bam suffix
- const auto outputPrefix = outputFile.substr(0, outputFile.size() - 4);
- // Save dataset
- std::ofstream ccsOut(outputPrefix + ".consensusreadset.xml");
- ccsSet.SaveToStream(ccsOut);
- } else if (outputExt == "fastq" || outputExt == "fq")
+ // File path without .bam suffix
+ const auto outputPrefix = outputFile.substr(0, outputFile.size() - 4);
+ // Save dataset
+ std::ofstream ccsOut(outputPrefix + ".consensusreadset.xml");
+ ccsSet.SaveToStream(ccsOut);
+ }
+ } else if (outputExt == "fastq" || outputExt == "fq") {
writer = async(launch::async, FastqWriterThread, ref(workQueue), ref(outputFile));
- else
- parser.error("OUTPUT: invalid file extension: '" + outputExt + "'");
+ } else {
+ std::cerr << "OUTPUT: invalid file extension: '" + outputExt + "'" << std::endl;
+ }
unique_ptr<vector<Chunk>> chunk(new vector<Chunk>());
map<string, shared_ptr<string>> movieNames;
@@ -579,7 +504,7 @@ int main(int argc, char** argv)
// check if we've started a new ZMW
if (!holeNumber || *holeNumber != read.HoleNumber()) {
- if (chunk && chunk->size() >= chunkSize) {
+ if (chunk && chunk->size() >= settings.ChunkSize) {
workQueue.ProduceWith(CircularConsensus, move(chunk), settings);
chunk.reset(new vector<Chunk>());
}
@@ -645,7 +570,7 @@ int main(int argc, char** argv)
// wait for the writer thread and get the results counter
// then add in the snr/minPasses counts and write the report
auto counts = writer.get();
- const string reportFile(options.get(OptionNames::ReportFile));
+ const std::string& reportFile = settings.ReportFile;
if (reportFile == "-")
WriteResultsReport(cout, counts);
@@ -654,5 +579,14 @@ int main(int argc, char** argv)
WriteResultsReport(stream, counts);
}
- return 0;
+ return EXIT_SUCCESS;
+}
+
+// Entry point
+int main(int argc, char* argv[])
+{
+ const auto version =
+ PacBio::UnanimityVersion() + " (commit " + PacBio::UnanimityGitSha1() + ")";
+ return PacBio::CLI::Run(argc, argv, ConsensusSettings::CreateCLI(DESCRIPTION, version),
+ &Runner);
}
diff --git a/include/pacbio/consensus/Polish.h b/src/matrix/BasicDenseMatrix.cpp
similarity index 67%
copy from include/pacbio/consensus/Polish.h
copy to src/matrix/BasicDenseMatrix.cpp
index 5eedc1a..9504ed5 100644
--- a/include/pacbio/consensus/Polish.h
+++ b/src/matrix/BasicDenseMatrix.cpp
@@ -33,44 +33,38 @@
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
-#pragma once
+// Author: David Alexander
-#include <tuple>
-#include <vector>
+#include "BasicDenseMatrix.h"
-#include <pacbio/consensus/Mutation.h>
-#include <pacbio/consensus/PolishResult.h>
+#include <stdexcept>
namespace PacBio {
namespace Consensus {
-// forward declaration
-class AbstractIntegrator;
-
-struct PolishConfig
+BasicDenseMatrix::BasicDenseMatrix(size_t rows, size_t cols)
+ : nCols_(cols), nRows_(rows), entries_(new double[nRows_ * nCols_])
{
- size_t MaximumIterations;
- size_t MutationSeparation;
- size_t MutationNeighborhood;
-
- PolishConfig(size_t iterations = 40, size_t separation = 10, size_t neighborhood = 20);
-};
+}
-PolishResult Polish(AbstractIntegrator* ai, const PolishConfig& cfg);
+BasicDenseMatrix::~BasicDenseMatrix() { delete[] entries_; }
-struct QualityValues
+void BasicDenseMatrix::ToHostMatrix(double **mat, int *rows, int *cols) const
{
- std::vector<int> Qualities;
- std::vector<int> DeletionQVs;
- std::vector<int> InsertionQVs;
- std::vector<int> SubstitutionQVs;
-};
-
-std::vector<int> ConsensusQualities(AbstractIntegrator& ai);
+ *mat = new double[Rows() * Columns()];
+ *rows = Rows();
+ *cols = Columns();
+ for (size_t i = 0; i < Rows(); i++) {
+ for (size_t j = 0; j < Columns(); j++) {
+ (*mat)[i * Columns() + j] = (*this)(i, j);
+ }
+ }
+}
-QualityValues ConsensusQVs(AbstractIntegrator& ai);
+size_t BasicDenseMatrix::UsedEntries() const { throw std::runtime_error("Unimplemented!"); }
-std::vector<Mutation> Mutations(const AbstractIntegrator& ai);
+float BasicDenseMatrix::UsedEntriesRatio() const { throw std::runtime_error("Unimplemented!"); }
-} // namespace Consensus
-} // namespace PacBio
+size_t BasicDenseMatrix::AllocatedEntries() const { throw std::runtime_error("Unimplemented!"); }
+}
+}
diff --git a/src/EvaluatorImpl.h b/src/matrix/BasicDenseMatrix.h
similarity index 56%
copy from src/EvaluatorImpl.h
copy to src/matrix/BasicDenseMatrix.h
index 28524d8..46f850d 100644
--- a/src/EvaluatorImpl.h
+++ b/src/matrix/BasicDenseMatrix.h
@@ -33,63 +33,59 @@
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
-#pragma once
-
-#include <memory>
-#include <utility>
-#include <vector>
+// Author: David Alexander
-#include <pacbio/consensus/Evaluator.h>
-#include <pacbio/consensus/Template.h>
-#include <pacbio/data/Read.h>
+#pragma once
-#include "Recursor.h"
-#include "matrix/ScaledMatrix.h"
+#include <cstddef>
+#include "pacbio/consensus/AbstractMatrix.h"
namespace PacBio {
namespace Consensus {
-class EvaluatorImpl
+//
+// BasicDenseMatrix is a *basic* dense matrix, for use as an
+// intermediate in matrix viewing operations (not in production code).
+//
+// It does not fully implement the interface that would be required to
+// drop it in as a replacement for ScaledMatrix in the production code
+// (i.e. for the recursor, etc.). ConsensusCore did offer such a
+// matrix, "DenseMatrix", and we could consider resurrecting such a
+// class in the future.
+//
+class BasicDenseMatrix : public AbstractMatrix
{
-public:
- EvaluatorImpl(std::unique_ptr<AbstractTemplate>&& tpl, const PacBio::Data::MappedRead& mr,
- double scoreDiff = 12.5);
-
- std::string ReadName() const;
-
- double LL(const Mutation& mut);
- double LL() const;
-
- // TODO: Comments are nice! Explain what this is about---ZScore calculation?
- std::pair<double, double> NormalParameters() const;
-
- double ZScore() const;
-
- bool ApplyMutation(const Mutation& mut);
- bool ApplyMutations(std::vector<Mutation>* muts);
-
- int NumFlipFlops() const { return numFlipFlops_; }
-
-public:
- const AbstractMatrix& Alpha() const;
- const AbstractMatrix& Beta() const;
-
private:
- void Recalculate();
-
-private:
- std::unique_ptr<AbstractRecursor>
- recursor_; // TODO: does this need to be a pointer? is it always non-null?
- // are we making it a UP just so we can do a fwd decl and still have
- // RAII semantics?
- ScaledMatrix alpha_;
- ScaledMatrix beta_;
- ScaledMatrix extendBuffer_;
+ size_t nCols_;
+ size_t nRows_;
+ double* entries_;
+
+public: // structors
+ BasicDenseMatrix(size_t rows, size_t cols);
+ BasicDenseMatrix(const BasicDenseMatrix& other) = delete;
+ ~BasicDenseMatrix();
+
+public: // Size information
+ size_t Rows() const;
+ size_t Columns() const;
+
+public: // accessors
+ double& operator()(size_t i, size_t j) const;
+
+public: // AbstractMatrix interface
+ void ToHostMatrix(double** mat, int* rows, int* cols) const;
+ size_t UsedEntries() const;
+ float UsedEntriesRatio() const;
+ size_t AllocatedEntries() const;
+};
- int numFlipFlops_;
+inline size_t BasicDenseMatrix::Rows() const { return nRows_; }
- friend class Evaluator;
-};
+inline size_t BasicDenseMatrix::Columns() const { return nCols_; }
-} // namespace Consensus
-} // namespace PacBio
+inline double& BasicDenseMatrix::operator()(size_t i, size_t j) const
+{
+ return entries_[i * Columns() + j];
+}
+}
+}
diff --git a/src/matrix/ScaledMatrix.h b/src/matrix/ScaledMatrix.h
index 2a37758..a3c872a 100644
--- a/src/matrix/ScaledMatrix.h
+++ b/src/matrix/ScaledMatrix.h
@@ -46,6 +46,8 @@
namespace PacBio {
namespace Consensus {
+/// This class inherits from SparseMatrix and extends it by having a
+/// column-wise scaling factor.
class ScaledMatrix : public SparseMatrix
{
public:
@@ -56,27 +58,39 @@ public:
};
public: // constructor/destructor
+ /// Constructor with explicit dimensions.
ScaledMatrix(size_t rows, size_t cols, Direction dir);
+ /// Copy constructor.
ScaledMatrix(const ScaledMatrix& other);
+ /// Destructor.
~ScaledMatrix(void) override = default;
public:
+ /// Clears and resizes the internal data structures.
void Reset(size_t rows, size_t cols) override;
+ /// Set direction and reset column-wise log scalars.
Direction SetDirection(Direction dir);
public: // nullability
+ /// Returns a ScaledMatrix representing null.
static const ScaledMatrix& Null();
public: // information about entries filled by column
+ /// Rescale column j by max_val.
+ /// If maxProvided is false, determine max_val.
template <bool maxProvided>
void FinishEditingColumn(size_t j, size_t usedBegin, size_t usedEnd, double max_val = 0.0);
public: // Scaling and normalization
+ /// Get the log scale for column j.
double GetLogScale(size_t j) const;
+ /// Get the log scales from colum s to e
double GetLogProdScales(size_t s, size_t e) const;
+ /// Get the log scale
double GetLogProdScales() const;
public: // Convenient matrix access for SWIG
+ /// Convert sparse to full matrix.
void ToHostMatrix(double** mat, int* rows, int* cols) const override;
private:
diff --git a/src/matrix/SparseMatrix.h b/src/matrix/SparseMatrix.h
index cb9cf4d..02ab03e 100644
--- a/src/matrix/SparseMatrix.h
+++ b/src/matrix/SparseMatrix.h
@@ -49,18 +49,25 @@
namespace PacBio {
namespace Consensus {
+/// The SparseMatrix is based on a vector of SparseVectors.
class SparseMatrix : public AbstractMatrix
{
public: // Constructor, destructor
+ /// Constructor with explicit dimensions.
SparseMatrix(size_t rows, size_t cols);
+ /// Copy constructor.
SparseMatrix(const SparseMatrix& other);
+ /// Destructor.
virtual ~SparseMatrix();
public:
+ /// Clears and resizes the internal data structures.
virtual void Reset(size_t rows, size_t cols);
public: // Nullability
+ /// Returns a SparseMatrix representing null.
static const SparseMatrix& Null();
+ /// Returns if the both dimensions are zero.
bool IsNull() const;
public: // Size information
@@ -68,22 +75,36 @@ public: // Size information
size_t Columns() const;
public: // Information about entries filled by column
+ /// Prepared the underlying SparseVector of column j
+ /// from rows hintBegin to hintEnd.
void StartEditingColumn(size_t j, size_t hintBegin, size_t hintEnd);
+ /// Finish editing column j and store the used rows in usedRanges_.
void FinishEditingColumn(size_t j, size_t usedBegin, size_t usedEnd);
+ /// Retreive the row range for column j.
std::pair<size_t, size_t> UsedRowRange(size_t j) const;
+ // Checks if no rows are set for column j.
bool IsColumnEmpty(size_t j) const;
+ /// Computes the number of filled cells.
size_t UsedEntries() const override;
+ /// Computes the ratio of filled cells.
float UsedEntriesRatio() const override;
- size_t AllocatedEntries() const override; // an entry may be allocated but not used
+ /// Computes the number of allocated cells.
+ /// An entry may be allocated but not used.
+ size_t AllocatedEntries() const override;
public: // Accessors
+ /// Access cell at row i and column j.
+ /// If not allocated, return 0.
const double& operator()(size_t i, size_t j) const;
+ /// Checks if cell is allocated.
bool IsAllocated(size_t i, size_t j) const;
double Get(size_t i, size_t j) const;
void Set(size_t i, size_t j, double v);
+ /// Clear content of column j and reset respective row range.
void ClearColumn(size_t j);
public:
+ /// Convert sparse to full matrix.
void ToHostMatrix(double** mat, int* rows, int* cols) const override;
private:
diff --git a/src/poa/PoaGraph.cpp b/src/poa/PoaGraph.cpp
index 7e7abcc..c663fd3 100644
--- a/src/poa/PoaGraph.cpp
+++ b/src/poa/PoaGraph.cpp
@@ -91,6 +91,11 @@ void PoaGraph::WriteGraphVizFile(const string& filename, int flags, const PoaCon
impl->WriteGraphVizFile(filename, flags, pc);
}
+void PoaGraph::WriteGraphCsvFile(const string& filename) const
+{
+ impl->WriteGraphCsvFile(filename);
+}
+
PoaGraph::PoaGraph() { impl = new detail::PoaGraphImpl(); }
PoaGraph::PoaGraph(const PoaGraph& other) { impl = new detail::PoaGraphImpl(*other.impl); }
diff --git a/src/poa/PoaGraphImpl.cpp b/src/poa/PoaGraphImpl.cpp
index 9a7d68c..789e1ec 100644
--- a/src/poa/PoaGraphImpl.cpp
+++ b/src/poa/PoaGraphImpl.cpp
@@ -448,6 +448,23 @@ void PoaGraphImpl::WriteGraphVizFile(const string& filename, int flags,
outfile.close();
}
+void PoaGraphImpl::WriteGraphCsvFile(const string& filename) const
+{
+ std::ofstream outfile(filename.c_str());
+
+ std::list<VD> sortedVertices(num_vertices(g_));
+ topological_sort(g_, sortedVertices.rbegin());
+
+ outfile << "Id,Base,Reads,SpanningReads,Score,ReachingScore" << std::endl;
+ for (const VD v : sortedVertices) {
+ PoaNode& vi = vertexInfoMap_[v];
+ outfile << vi.Id << "," << vi.Base << "," << vi.Reads << "," << vi.SpanningReads << ","
+ << vi.Score << "," << vi.ReachingScore << std::endl;
+ }
+
+ outfile.close();
+}
+
} // namespace detail
} // namespace Poa
} // namespace PacBio
diff --git a/src/poa/PoaGraphImpl.h b/src/poa/PoaGraphImpl.h
index 00a73d1..93e6d5b 100644
--- a/src/poa/PoaGraphImpl.h
+++ b/src/poa/PoaGraphImpl.h
@@ -256,6 +256,7 @@ public:
size_t NumReads() const;
string ToGraphViz(int flags, const PoaConsensus* pc) const;
void WriteGraphVizFile(const string& filename, int flags, const PoaConsensus* pc) const;
+ void WriteGraphCsvFile(const string& filename) const;
};
// free functions, we should put these all in traversals
diff --git a/swig/Matrix.i b/swig/Matrix.i
index 6ff6c94..ef854e8 100644
--- a/swig/Matrix.i
+++ b/swig/Matrix.i
@@ -1,6 +1,7 @@
%{
/* Includes the header in the wrapper code */
#include <pacbio/consensus/AbstractMatrix.h>
+#include <pacbio/consensus/MatrixViewConvention.h>
%}
#ifdef SWIGPYTHON
@@ -10,3 +11,4 @@
#endif // SWIGPYTHON
%include <pacbio/consensus/AbstractMatrix.h>
+%include <pacbio/consensus/MatrixViewConvention.h>
diff --git a/swig/Mutation.i b/swig/Mutation.i
index 92754da..ca10f04 100644
--- a/swig/Mutation.i
+++ b/swig/Mutation.i
@@ -7,3 +7,13 @@ py_tp_str(PacBio::Consensus::Mutation);
py_tp_str(PacBio::Consensus::ScoredMutation);
%include <pacbio/consensus/Mutation.h>
+
+namespace std {
+ %ignore vector<PacBio::Consensus::Mutation>::vector(size_type);
+ %ignore vector<PacBio::Consensus::Mutation>::resize;
+ %template(MutationVector) vector<PacBio::Consensus::Mutation>;
+
+ %ignore vector<PacBio::Consensus::ScoredMutation>::vector(size_type);
+ %ignore vector<PacBio::Consensus::ScoredMutation>::resize;
+ %template(ScoredMutationVector) vector<PacBio::Consensus::ScoredMutation>;
+ }
diff --git a/swig/State.i b/swig/State.i
index 161788e..948603f 100644
--- a/swig/State.i
+++ b/swig/State.i
@@ -3,4 +3,8 @@
#include <pacbio/data/State.h>
%}
-%include <pacbio/data/State.h>
\ No newline at end of file
+%include <pacbio/data/State.h>
+
+namespace std {
+ %template(StateVector) vector<PacBio::Data::State>;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 605ff2b..9816257 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -29,7 +29,6 @@ include_directories(SYSTEM
${ZLIB_INCLUDE_DIRS}
${HTSLIB_INCLUDE_DIRS}
${UNY_ThirdPartyDir}/seqan/include
- ${CPPOPTPARSE_IncludeDir}
unit/
${PacBioBAM_INCLUDE_DIRS}
)
diff --git a/tests/cram/100zmws.t b/tests/cram/100zmws.t
index 77a8634..4727181 100644
--- a/tests/cram/100zmws.t
+++ b/tests/cram/100zmws.t
@@ -1,11 +1,12 @@
Test ccs on 100 zmws from the lexogen-SIRV dataset
- $ $__PBTEST_CCS_EXE --logLevel=DEBUG --minZScore -100 --maxDropFrac 0.8 $TESTDIR/../data/100zmws.bam test.fq
+ $ $__PBTEST_CCS_EXE --logLevel=DEBUG --minZScore -100 --maxDropFraction 0.8 $TESTDIR/../data/100zmws.bam test.fq
>|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- main -|- [0-9,a-f,x]+|| -|- Found consensus models for: (P6-C4, S/P1-C1) (re)
>|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- main -|- [0-9,a-f,x]+|| -|- Using consensus models for: (P6-C4) (re)
- >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- Consensus -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/413/9570_12297, ALPHA/BETA MISMATCH (re)
- >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- Consensus -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2359/6103_8488, ALPHA/BETA MISMATCH (re)
+ >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- operator() -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/413/9570_12297, ALPHA/BETA MISMATCH (re)
+ >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- operator() -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/4100_6514, ALPHA/BETA MISMATCH (re)
+ >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- operator() -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2359/6103_8488, ALPHA/BETA MISMATCH (re)
$ grep -c ^@ test.fq
100
$ cat test.fq
@@ -33,10 +34,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset
AAGCAGTGGTATCAACGCAGAGTACGGGGATTGGATTAAAAAAGTTGTAGTAAACCACAACGAAGTTAGGTAGCTGGTAAGGTTATAGATGCGTTCTGTCGTTGTAGTCCCAATGAACATAGTATGGTTTCGCATAGTAACTGACCTAAAAGACCGCCACATAGTGAAAATACTTAAAACGCAAGTTTCATAGGATTAAGTGGTAGAGGCTATAGAAAATGATATCATAACTATAACGAATATAACAGCAAATTAAAATGCACTGGAAGTGGAAAATTTCAGCAAGAGAGTCGAAGTCGTCATAGATTAGCATGGACGAAAGAAAAGTCGCAAAGATCGGAAATCAAGACGCAAAACAAAACGGAGAAGTTCAAATCGAACTCGTAGAACATATCGCTGGAACATATTAAACTCTTGGTATCGCTCAGTTACAAAAGGAGACACGTAGACACGAAAGAAACTGGAACAACAGACATATTTGTGGATAATG [...]
+
~~~~~~~b~~~~~~~sxw~~~b~~~T~~~~~~p~~~~D~~~~~~h~~~~t~\~~_~~u~~~~~~tx~~~~~~~~~q~~~~u~~~~~~~~~~~~~~~~~~~~q~~~d~~Y~~~~~~|~X~~~~^x~r~~~~~xy}~~~~]~~~r~m~~R~~~~~o~~X~}~zw~~~uX~~~~~~~~^~~~u~~~~~~~~~~~~v~~~~~~~~r~~~~~a~~~~~~z^~~~~~~~~~~~~~~~~~~o~~~z~~~~~~~~~~|~~~~]~~~~~~~~~x~~~~~p~c~~~o~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~k~~~~~~~e~~~~~~~~~~~~u~~~~~~b~~~~~~~~~~v~~e~~~~b~~~~~~~|~~~z~~`~~~~zA~~~~O~~~~~~~~~~~~~~p~~~~~~~~~l~~~~~~~h~~~~~~c~~~~i~~}t~~~q~~~~|~~~~~~~~~~~S~~~Y~~~~~~~~S~~~~~~~~~~_~~~~~~~~~~~~ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/418/ccs np:i:10 rq:f:0.999163
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTGATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTTGTGGGCTAGGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAATTTACGGTGGTAATTTCGCACACTTCGCACGTTT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/418/ccs np:i:10 rq:f:0.998932
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTGATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTTGTGGGCTAGGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAATTTACGGTGGTAATTTCGCACACTTCGCACGTTT [...]
+
- I~~}~~tX~~~~jf~|~k~|~~O~q'~~~~~~~~~~~~~~~~~~~~~~~~~idrv~c{mjY~h~~we}~dF~b~~i~@~x~~T~~~~~~m~~~tT~~~m~K~~I~`x~n~Y~~o~]~~~m~Y~~X~&~[[~~~q~~~l'~~~Z~ifN~dH~~~~~E~~~~~t~{~T~~~X~M~~i~z~~~m~~~d~}~z|k~~~MeH~~l~~Q~~~~~~~~;~wa~V~~@~~j~J~~~qq\~~~n~~~~~d~|~U~~~~~W~~y~T~ym~F~~~}c~j~^~~}~~~~pNV~Y~ob[~kV~~^q@~~~~~]~sX%Mk~~~%~oAmW[~zp~pdf~~:VYsW@}~~~f~~e}~~~k~l~n~n~i~f~L~\~~~~~~{O~~Z~S~~k~~~~~~~}~~~~X~~itbX~QU~wS~~j~j~~f~f|h~ukpii~b`g~~tphY~j~~bTp~~~~t~~k~~p~o~rn~~~s_~^~~ImU~rk~~_~i~~~^~n\h~f~qnoi]rE~~ [...]
+ I~~}~~tX~~~~jf~|~k~|~~O~q'~~~~~~~~~~~~~~~~~~~~~~~~~idrv~c{mjY~h~~we}~dF~b~~i~@~x~~T~~~~~~m~~~tT~~~m~K~~I~`x~n~Y~~o~]~~~m~Y~~X~&~[[~~~q~~~l'~~~Z~ifN~dH~~~~~E~~~~~t~{~T~~~X~M~~i~z~~~m~~~d~}~z|k~~~MeH~~l~~Q~~~~~~~~;~wa~V~~@~~j~J~~~qq\~~~n~~~~~d~|~U~~~~~W~~y~T~ym~F~~~}c~j~^~~}~~~~pNV~Y~ob[~kV~~^q@~~~~~]~sX%Mk~~~%~oAmW[~zp~pdf~~:VYsW@}~~~f~~e}~~~k~l~n~n~i~f~L~\~~~~~~{O~~Z~S~~k~~~~~~~}~~~~X~~itbX~QU~wS~~j~j~~f~f|h~ukpii~b`g~~tphY~j~~bTp~~~~t~~k~~p~o~rn~~~s_~^~~ImU~rk~~_~i~~~^~n\h~f~qnoi]rE~~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/420/ccs np:i:20 rq:f:0.999865
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGGTAAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCT [...]
+
@@ -45,10 +46,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset
AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTA [...]
+
i~~d~~~b~~~[~}~~Vizw~~~~~M~~~~e~b~~~~~}F~~t~~v~D~~i~~~~zi~~s~r~~~H~~~~~~~~~~2~~~~~~~~f~r~o~~~~i~~~~~u~~u~~~~~~~~~~~b~~uuuz~~~U~~~~~~k~~~~~~s~~~~~~~~y~~m~~~~|r~~~~~~~~~~~~~x~~w~z~~~~~~~}~~uj~~j~~~z~~~\~~~~~~~~~~~~~X~~c~]~9~~~g~~~~~~~~~~~rj~~~~uv]~~~~~~~~~~~~~~~m~v~~~v~~~~~~~R~V~~akn~~w~~w^~~~~~~~~z~\~~~n~~~~~~~~~}~~~~~~~~b~~~~h~~~~Y~~~~~l~~y~~~~~~~~~~~ym~~~~~~}~~~}~~i}~~~~~p~x~~~~~~~~~~~t~~~~w~~nr~~~k~~~~~~z~~~v~~~~~uW~w~~~~~~~~~w~~{~~hW~^~~c~c~H~W}~~~~x~w~~r~~~~~p~~~j~|~~~~y~~M~~~m~~~~ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/ccs np:i:10 rq:f:0.999251
- AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAAT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/ccs np:i:10 rq:f:0.9993
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAAT [...]
+
- {~~~~~~o~~~~mk~n~~~yn~~~~b~~~~~z~~~~d^~~~{X~z~~~||z{~~o~z~~k~~~~|~~z~~~k~~~~~rQ~~~~]~~~~~~~~~o~~~~~~~U~l~Q~~~~|~~H~~~~~~]~~o~~~~~~~z~u~~~~~^~~}r~~~[~~~m~~U~~x~~~~~u~~~~~~~~~n~~~~~~~]~~~~~F~~~~l~~~~}~\~~x~X~~~~~~~e~o~~~~~~)~~~~~~g~{~D~~~~eW~~~~~~~~~~~~~~~~}~~~{~~~r~~z~{~m~v~~~~~y~`L~~w~~~_~~~~~~d~~~~~~x~C~~~~~~~J~j~v~~~~{~~~~~~j~~~d~~~~~n~~~~~v~~~j~~l~~~~r~~~\~~~p~~~~~~\~~~~~~N{lcm~o~~~o~~~~~~~~~f~~~~~|~~~c~~~~Z~zLy~~~~~~~~~~~]~w~~~~~~~D~~~~~~~~~m~~~~~~q~~y~~~|~~~~~w~~{~~~~~~~~~~~nuqz~~ [...]
+ n~~}~~~d~~~~`r~ww~~on~~~~X~~~~~v~~~~dN~~~lP~s~~~p~ps~~q~m~~b~u~~q~~v~~~a~~w~~mV~~v~V~~~~~~u~~c~~~~~~~Q~q~E~~~~o~u:~~~~~~O~~a~~~~~~{s~s~~~~sP~~~r~~~c~~~a~~L~~~~~~~sp~w~~~w~~~d~~~~~~~f~~~~~F~~~~a~~~~qoS~~o~Q~~~~~~~_~f~~~u~~/~~~~~~a~o~7~~~~nO~~~r~~~u~~~~~~~u~~~~p~~~l~~p~q~p~u~~~}}~~fP~~v~~~f~~~~~~W~~v~~~l~7~~~~~w~=~]~q~~~{p~~~~~~c~~va~t~~~a~~~~~p~~~j~~^~~u~f~~~Q~~~m~r~~~~N~~~~~|Gqtlazr~{~d~~~~~t~~~^~~~~~p~u~W~~~~a~~Nm~~~~~~~~~z~Q~q~~~~~~~H~~~~tr~~xc~~psu~e~~r~~s~~~~v~g~y~~~~q~~~~~~~crbv~~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/456/ccs np:i:17 rq:f:0.999773
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGGTAACTATCTTAAAAACTTCTAAACTGCTGCTTAGTAGGCAATAATCGACTAAATCCATAATTTTTGCGACCAAACGCAAACTTCAAGAATTTTAGACTTTGAAGACCGCATCGGCAAACCCCATTTTAGATACCACTTTAATTTCCAGTTAATCTACGACGCAAGTCACTTCTTTGTCGTTAAGTTTTATTTAACTGTCGCAAACAACAAAATGGTTTTCTAAATTTACTAAAACCAGGACGCACCTAACTTTCTAAACAAGCACAAGTTTAGCTTCTTCGTAAACGTCACCGCGAACTTTGACGCAAGAATTTTCCATGACCATTTCTGGTTGGTTAGCCGAATTTGGCAGTTCATGTTTTTCCACATAGCCATTGACTCCCACGAATAGGTCTCTTTCTTCTTGTTCCATGCGAATGTAAACGATTAGGCG [...]
+
@@ -229,10 +230,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTCGCCACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGGTTTGCACTGTTGACCACCAGCACGCAATCGCAAGATACGCAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGCTACACATATGCTGTTGGGAATGTTTTTTACACTTATTATG [...]
+
~~~~~~~N~~~~~~~~~~~~~~~~~*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s~~~~~~~~~~~~~~~~{v~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~~~~Y~k~e~~~~~~~~~~~~~~~~~~~x~~j~~~]~~~r~~~~~~~~~~~~~~~~~~x~~~~~x~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~V~~~~~~~~~~~~~~~~~~~s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f~~z~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]~~~~~~~~~~~~~~~~~ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1999/ccs np:i:10 rq:f:0.999526
- AAGCAGTGGTATCAACGCAGAGTACGGGGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTGACCCAAATAATAAACTCGTTCCAATAGTTGAAGTGTTGATTAACACATTGAGACAAGTTGTCCGTACTTTAATCATCAAAGTTTTGGACTGACCTATAAATGAAATATTCGCGTTGTCTTCAGTTTAAGAAGTGATATTATTTTCGGTTTCAAGCCTATGTGGAGAGATACAGGAAATAGGTAAACTATAACTAATATAAATATACGCAGACGAAGCCTGTTAACTTTACCAAATCCAAATAGCGGGAGAC [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1999/ccs np:i:10 rq:f:0.999415
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTGACCCAAATAATAAACTCGTTCCAATAGTTGAAGTGTTGATTAACACATTGAGACAAGTTGTCCGTACTTTAATCATCAAAGTTTTGGACTGACCTATAAATGAAATATTCGCGTTGTCTTCAGTTTAAGAAGTGATATTATTTTCGGTTTCAAGCCTATGTGGAGAGATACAGGAAATAGGTAAACTATAACTAATATAAATATACGCAGACGAAGCCTGTTAACTTTACCAAATCCAAATAGCGGGAGAC [...]
+
- r~~~~~~`~~~~~~~~~s~~~~~~~d~~~~m~~~~d~~~~~~~~v~~~~~~~~ji~~~~~~q~e~2~~r~~~Y~~~~~~~~~~~~~~~h~~~~U~~~~~|~~~~~~~\~~~~~~|~~_~~~~~~r~~~P~~~~~G~~~~~~~~v~~~k~~~~~~~~_~~~~~~~y~~~ov~~~y~h~v~~~j~~~~~~~m~~~~~~~a~~~~~~~u~u~~~~~U~~~~~~~~~j~~~~~~~~M~~~~~~~`~~f~~~~~ce~~q~~~~~`~~~~~~b~|\~~~lt~~~}~_~~~~~t~~~~~~j~p~~f~~~~~~~R~~~~~~~Z~q~~~F~~~o~~~~~~j~~~~W~~~~k~~~p~~v~~~U~~~~U~~~~W~~p~~j~~p~~~~n~~@~~~~|~h~~~s~~~~~k~~~f~|G~w~~~n~`~A~~~~~~~U~~~|~~~~~~~~~~~{~~~~~~~s~~~~~~~~~o~~[^~~~~s~~~~~p~~~z~l~~~~~~P~~~~~~ [...]
+ r~~~~~~`~~~~~~~~~s~~~~~~~d~~~~m~~~~d~~~~~~~~v~~~~~~~~ji~~~~~~q~e~2~~r~~~Y~~~~~~~~~~~~~~~h~~~~U~~~~~|~~~~~~~\~~~~~~|~~_~~~~~~r~~~P~~~~~G~~~~~~~~v~~~k~~~~~~~~_~~~~~~~y~~~ov~~~y~h~v~~~j~~~~~~~m~~~~~~~a~~~~~~~u~u~~~~~U~~~~~~~~~j~~~~~~~~M~~~~~~~`~~f~~~~~ce~~q~~~~~`~~~~~~b~|\~~~lt~~~}~_~~~~~t~~~~~~j~p~~f~~~~~~~R~~~~~~~Z~q~~~F~~~o~~~~~~j~~~~W~~~~k~~~p~~v~~~U~~~~U~~~~W~~p~~j~~p~~~~n~~@~~~~|~h~~~s~~~~~k~~~f~|G~w~~~n~`~A~~~~~~~U~~~|~~~~~~~~~~~{~~~~~~~s~~~~~~~~~o~~[^~~~~s~~~~~p~~~z~l~~~~~~P~~~~~~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2012/ccs np:i:11 rq:f:0.999194
AAGCAGTGGTATCAACGCAGAGTACGGGGCTTGTCCGCGAGTGTCAACCGGGTTTTACAAAGGAGAACTTCCAACATCAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTGTGAGGCGCAAGGTACATGCTCTTACCCCACTCTCAGCACGTAGGGAGCGGAGTGTGGAAGACCAACAAGCCCGTCGCCTCTACCAAATACAGCTATCCTGAGGTGCCAGGTTAGAATAGGCCCTACCACATCTAAGCCTTGAAACGGTCTGTTCCTCGTGTCAAGTTCTTGTCCGCTTATACCGCCATCTCTCGTTGTGGTACAAGAGTTGGTTACTCTCAGTCCCATTCCCAACACATCACTGAGAAGTATAGAGCCTAGTGGTCATTAGAAGGTCAACATGGAGTAGGTGTTTAGGTGTGTCGGAGGGCAGAAACCAA [...]
+
diff --git a/tests/cram/100zmws_byStrand.t b/tests/cram/100zmws_byStrand.t
index 680d151..81f8f5f 100644
--- a/tests/cram/100zmws_byStrand.t
+++ b/tests/cram/100zmws_byStrand.t
@@ -1,11 +1,12 @@
Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
- $ $__PBTEST_CCS_EXE --logLevel=DEBUG --minZScore -100 --maxDropFrac 0.8 --byStrand $TESTDIR/../data/100zmws.bam test.fq
+ $ $__PBTEST_CCS_EXE --logLevel=DEBUG --minZScore -100 --maxDropFraction 0.8 --byStrand $TESTDIR/../data/100zmws.bam test.fq
>|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- main -|- [0-9,a-f,x]+|| -|- Found consensus models for: (P6-C4, S/P1-C1) (re)
>|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- main -|- [0-9,a-f,x]+|| -|- Using consensus models for: (P6-C4) (re)
>|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- Consensus -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/413/9570_12297, ALPHA/BETA MISMATCH (re)
- >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- Consensus -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2359/6103_8488, ALPHA/BETA MISMATCH (re)
+ >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- operator() -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/4100_6514, ALPHA/BETA MISMATCH (re)
+ >|> \d{8} \d{2}:\d{2}:\d{2}\.\d{3} -|- DEBUG -|- operator() -|- [0-9,a-f,x]+|| -|- Skipping read m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2359/6103_8488, ALPHA/BETA MISMATCH (re)
$ grep -c ^+$ test.fq
200
@@ -87,10 +88,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAAACAGCAATAATTGTAGAAGGTAGCAATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGAC [...]
+
H|_GO;,R}fcL+C`AJV`[P`ePWA|||V|QoO`^a=amKH*y`WgfXbfR}fR{Pe`DwA`aR{fgaW`FzV`OT:HofA\@eyffffWaU4tL[[gff)`0D5~|efGfJ&wwYUM_VFxdG^WzagfaW}R}ff`B,d`ecDN^\H~af`P_9}eOVgfUIG|`fJWA`fa6~]K`Y}aE~|a_a$xx`adJdfadJe2|H;C:pfrUPed6|<t`bR~c3fjgVW|Jb<M/YDXePO|}dAdW|HU`fWfaa?MVe`E{eaJTf^hQ}fMP~W}abbbHAzVacR`agWK~ae6~vTjWbMJ0Zbc`dA^4_7jP]fcFR|fW}^IIznAFyVfbY at zfaa`fOhN:U_3w^@NO||U:vc]O{RmUQ`9~eafTQ'?^OEO8O_N<~f`YOVea`;L``eWcXW{:ljm`=emIDz_NUPeagfae>yDz]\VRSR2__vO?8W|_2jF6@`e:~e at vaWKzW_Aea\aT|TaY}faY}_OK>D [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/ccs/rev np:i:5 rq:f:0.992297
- AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTGACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAAT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/429/ccs/rev np:i:5 rq:f:0.991542
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAATG [...]
+
- IhWbcRV>rdg\cH}NWT^>@W_\_+Vg[MjFtbV]&?imXQO_9bhfF;4Hhh<z at _KH{cdQB^H5SMYGgZDbcY$PcdY>q\WeUbKXc[xhFaRWWMyVd<TbRXUlY'kabcYa8h?:jVyWchG9X*TSeZdhUN>QISO4tUL.?G3}g)QaPgbWQsCQiYdWRUB}yiZNlY9aYHMHGzzZYDdaY[T73h_^]6op_PUUQP]9hhhLqc2kw]Rp>OJW6hjk\7*ZnXPZM`ZcZUdiYicRbQUQndSHiY<>GC)aDgOWHI8/8-^Y6QNA]49ZmQXMolHpaGKJ4gDfIXQK7tSiGTYacJi<TkPU=Shb at kLU@WMlgA^Z1K_FP*KUqP`\ClgbClp`@`Hlbc^DpdTT]PI\.5IWXgGLSwQRNOKVN`LTeIU^9YBdGgggd3\.&RmT``^CVEcEC?ZIsNS\hjb2~og``i:TEYsXjbA`GlaT}RKC`AS_L7]DGz]WFOhZSgY^DYNQwQ [...]
+ FiMW[NY3oY[[WOmWNWX4?K[[R0MZWMkCpZNV&2dgXBFU4U[X:B+AdZ>f5TM?lVYB at jO0IPM<kT8YWT+R`VM7lfWXXV?LVOm[KSIWIGiJi0OeY[JmM/laV[NU+i.+iMlN[Z;1O/OFYNWZXA at QPXN<fJQ%GK2c5/UDYVKId8BXNWMBL8kkZNNmLA``DUKEhhNY8YZMQH,6UkUZ7mmkVZ[[Jm?nmZApY'jjUMf8WPZ*jjjh?$edMLOHONWN[W[N[W[WYKJk[ZAkO3@@N+VBkHS><?:?0RS5XT>'1>OmN[Amk<jUF at R)hN[KSUM*iHkBL[[V?m at NmNZ:WjV<k?XDLAmkAVX,ITLQ)IKlNWZ8kkU8llY=R<jV[Y6iYN[ZMBS7>=L[Z=WIlDYOV?YOZDZX=VR.S=\<lmm[;[<'JiIYRPCLDT:O5XLlLPWY[S2ll`QV[BS:NlN[T5OHm[IlB>Hc1NV@(S8NkWM9SZNNmMU9U?JnY6 [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/456/ccs/fwd np:i:8 rq:f:0.999079
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGGTAACTATCTTAAAAACTTCTAAACTGCTGCTTAGTAGGCAATAATCGACTAAATCCATAATTTTTGCGACCAAACGCAAACTTCAAGAATTTTAGACTTTGAAGACCGCATCGGCAAACCCCATTTTAGATACCACTTTAATTTCCAGTTAATCTACGACGCAAGTCACTTCTTTGTCGTTAAGTTTTATTTAACTGTCGCAAACAACAAAATGGTTTTCTAAATTTACTAAAACCAGGACGCACCTAACTTTCTAAACAAGCACAAGTTTAGCTTCTTCGTAAACGTCACCGCGAACTTTGACGCAAGAATTTTCCATGACCATTTCTGGTTGGTTAGCCGAATTTGGCAGTTCATGTTTTTCCACATAGCCATTGACTCCCACGAATAGGTCTCTTTCTTCTTGTTCCATGCGAATGTAAACGATTAGGC [...]
+
@@ -143,10 +144,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTA [...]
+
v~|KTskS~~y~`OvMPLi}h{}{d4~~m^U~B~~~}maX~~<~~w~Z~h0~~cc{@~}P~|~]UE~~~bf{c~~~'~~~PN~~bQ~i~h~h~mL~i~a~g~sJxP~xUxA~~^~J~~~OuB~~\(n~~Nd~7~yL~N~9FryQ|X~{z~xm{cyy_Xz~\gtz~krvbk~^s_~bj*~~O_g~W~zvCzmNz~~~~~~c~~~|bimb~igL}I~uJ~h}2~~{T~`cc~dWyjm]|N~y|~zcIl~~b~~b~~~la~\|y_bz~\N~}[}d~Q|~A~|afO~fOs~~T~Tp]yx}~~~8~zyK~Y~nbif~OY~~~b}aeMV|{~PC{~b}.~~}uee~~g~cu~y~i~M\~~M~~g~c~c~~b~~~|M|hk~bkzJ~~aYd~~~~SqL~~~`~~~~i~~}@z~wnCgU~~d_~a~~~~P~b~~e~~~~~9|~~=~f^\~2~~e~ez]{xz~d~cd~O~~g~y~j`?~~~h{QL~_jMwgO~~;i~e~h [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/705/ccs/rev np:i:9 rq:f:0.997386
- AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTA [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/705/ccs/rev np:i:9 rq:f:0.997074
+ AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTA [...]
+
- X~HL~<[:vd~wS[Y<Ze~_~N{~i3cgviZ~K~~u;hiE~~`t~gw3~w8v~_g`h~Oh~k~ey.^$ST~QhOb=-_df}b)zgo~RpMk%|vh~cxvwO~y`aT~~_~~vd~~F~~Wffh~mz8~~si\~h~dz}coYx~_~c~~b`vcX~C~~~U~~|~^U|`t6LMkU~~~bk\~~P|}~:~RJY~~p~~^z}9~~l`~a~`hi~_kfOQ~~M~~aFz~~yuU]~~~q~c~{Rf~~GTa~M~~{qOxi~~x~e:dQ~iM~gu[~~b~e]d`~f~~c`X~~g|]]z}|gj~wa}~`L~g~i~l~~}^Jx(SAw{|<cwfWzb~~8~B{aI~~~^Q@~b'~b~kWr\a|c~\-~{rzg`N|vMU~M~S~N~\j~bN~{byWa~ad~LRwbZpJeP[EzsRBk{~mY\Q~~~ia}g~ZOY~~~gxc>L~uqGFLY|RkBdGXT~zQ~|g~L~bg~>~[~sQ~~BM{}~P~]PK|Xhbi~{N~~|~~hf~ [...]
+ X~HL~<[:vd~wS[Y<Ze~_~N{~i3cgviZ~K~~u;hiE~~`t~gw3~w8v~_g`h~Oh~k~ey.^$ST~QhOb=-_df}b)zgo~RpMk%|vh~cxvwO~y`aT~~_~~vd~~F~~Wffh~mz8~~si\~h~dz}coYx~_~c~~b`vcX~C~~~U~~|~^U|`t6LMkU~~~bk\~~P|}~:~RJY~~p~~^z}9~~l`~a~`hi~_kfOQ~~M~~aFz~~yuU]~~~q~c~{Rf~~GTa~M~~{qOxi~~x~e:dQ~iM~gu[~~b~e]d`~f~~c`X~~g|]]z}|gj~wa}~`L~g~i~l~~}^Jx(SAw{|<cwfWzb~~8~B{aI~~~^Q@~b'~b~kWr\a|c~\-~{rzg`N|vMU~M~S~N~\j~bN~{byWa~ad~LRwbZpJeP[EzsRBk{~mY\Q~~~ia}g~ZOY~~~gxc>L~uqGFLY|RkBdGXT~zQ~|g~L~bg~>~[~sQ~~BM{}~P~]PK|Xhbi~{N~~|~~hf~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/734/ccs/fwd np:i:12 rq:f:0.998898
AAGCAGTGGTATCAACGCAGAGTACGGGGTGCTCGCCATTTCAACTAGTGCAGTTGCTAAAGTGCCAACTAAGGTTCGTCTTGAAGCAATCGGTAGTATCTGCAGTCAAGTCGTAGTCGTAGGTATGGCACTTGTCGTGCGTCTAGGACGCGTTGAAGCTATCTTATTGCCCGAAGGAGCCGAAAGTCTGGGACACGTCGTGGGACGTATCGTTAGGACTATGGGACTAGTCGTCTTCGGTCTTACAAATGTTGCAATGCCCTGTGAGCTACTTATGAAACATGAATGGTCGGTCTTGTGGTCGCTTTTGTCGAAATCACCGAAGTGCGTATAATTGATGAACGAGTCGAAGTCGAAGTTGTTCAACAAGAGAGTTAGGTAGTGCCGCTTGAAAAAGTAATAGTGCAAATAAGAAAGTAAGACTGTATCGGAGACGACTTTTTAATAGTAGTAATTCTCGGTACAACTAAACCAGTAATTTCAGACACTG [...]
+
@@ -271,10 +272,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTGCTAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTAGTGT [...]
+
N~e_zd~D~~j~JT~`r\zwituUL%~~~~~~~~~~~~~}{|~~~~~~~}|\R^y[puB~v]J~~_tzMw~`~xv_^o*^`NywsxNt~`t~v~cx\~]x~`whk[d~gI~he^~~`~T~[~gxxxwM~x~iP~lao-~b}^uV~~U~_~sxO~xbh~w:~w]Zt]~ZQz|\xL~y~M~?_iKuu~_YlMx:~e~tq]~d~O~~M~t~Q~~B~~~xvjw~zm_smAfX}zw_s}xfB~|L~ywH~pMc~}J~U~_aNQ~~uP~|iH\~hs@~m~nz`Sg[g<uc~J*~ke~tZ~`e~g~savQ~|r~V~}uDattax~A]C~\vR~~rD~*~vW~\~<~~`s~B~~<~_~~m~aY~W~~Mu~R~aQ`~Ya~Mu|w~@~e~~`X~yx|_{q~b~hvys,~~IvM~Xz7~tdu~e~c~~zwSq@~~~\yt[Tsb3k~]Md/poscU~~c\,~tUKT`^L~uL^|i~utI~~~~Vkx<~bK~~^|fJx~t~Go [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1334/ccs/rev np:i:9 rq:f:0.997849
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTATAAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTAGTG [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1334/ccs/rev np:i:9 rq:f:0.997545
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTATAAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTAGTG [...]
+
- _~`ugXp7~yrybr~]LsrGo]d~t%~{~~~~~~~iUIEIYmy~~~~{z|~~yssgDrVZ~x~i_T~}uy~a[e2m]0nI~N~vv~|>|vPfuZ?aq}~}~}T~~g~u~q~~I~~Rjp|~~~~D~tc~h~|zCn~'~@}[~b~~w>~~W~E~peZ~~|V~NDu|yadyk~~~~~~g~b~~~V~~L~~~~m~|sa~V~Y_F~X~>~i~~QoD~c,~~~~[b=W~X~h~`~f~~^|}~g~D~mN~~~G~~j]~~C~[~nWpm~iKGnzSS~_jgg~3|~hyOyh~jeRovF~~c~e~~~7~v~ojdY~{M~ux~B~~d~~Oky}}~ma;{~}d~{~dk~}qg~ny:~b~~c~M~~a~~?~`~~E~~o~xkrqkn~|u~gsg~6~}~c~~i~~~`~H~iS|RS~~m~g~;~H~~N\~z~@~~~Rh~H~~~~~d~~~dS~~~~?~~~j<~n\~Y~~z_y~eY~~j3~gp~e5~~~~j~QV~~h~s~~g~~~VoW [...]
+ _~`ugXp7~yrybr~]LsrGo]d~t%~{~~~~~~~iUIEIYmy~~~~{z|~~yssgDrVZ~x~i_T~}uy~a[e2m]0nI~N~vv~|>|vPfuZ?aq}~}~}T~~g~u~q~~I~~Rjp|~~~~D~tc~h~|zCn~'~@}[~b~~w>~~W~E~peZ~~|V~NDu|yadyk~~~~~~g~b~~~V~~L~~~~m~|sa~V~Y_F~X~>~i~~QoD~c,~~~~[b=W~X~h~`~f~~^|}~g~D~mN~~~G~~j]~~C~[~nWpm~iKGnzSS~_jgg~3|~hyOyh~jeRovF~~c~e~~~7~v~ojdY~{M~ux~B~~d~~Oky}}~ma;{~}d~{~dk~}qg~ny:~b~~c~M~~a~~?~`~~E~~o~xkrqkn~|u~gsg~6~}~c~~i~~~`~H~iS|RS~~m~g~;~H~~N\~z~@~~~Rh~H~~~~~d~~~dS~~~~?~~~j<~n\~Y~~z_y~eY~~j3~gp~e5~~~~j~QV~~h~s~~g~~~VoW [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1378/ccs/fwd np:i:5 rq:f:0.996097
AAGCAGTGGTATCAACGCAGAGTACGGGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAATGTT [...]
+
@@ -283,10 +284,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTTAAACTAAAACATACAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGGTTCATCCAGTTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAATGT [...]
+
WuS at D8A1RFATWBc:PU_TLQAFB7i]iFLTW8xpO0GqS at D[XQBAZGDlSYTIuV^E6ZW0=JTHtXUUW[+gKS<t\C,P^LULEm7RWUFWHsLmBt_AAEqT<toXaT<QmFTt?kT\bTIfD[G`TYb[UDX\CRFoRDNXTFuubYVRV>?jSB at PYTbTFuubTMuTKulE^>ErnO+Qb\T\T*@;ssWF8iulYb\]&<mI/@8D)prrW=rSX*\;euvuaDiTaWF+nQU(ZA_T_XaYbT=q^1Fe_>ZGvb\GwVuT\SFR=pV>_Y\T+^W?m9]2qqNuY\`FLsZGQ\YS1pFcGQ\aRBoFUtPX=[\A at rXbYTCwvbSPZG\>IJ>ToTYb;vcN;Vo[/dK:cU`D7p`R)eWTbYTbW:SSSVBKE]9DA_TIXb\T\TZV,h1Zso`;wiTQWSFXbY=C`KGBN1T>5K6]A2svviX`=@+?kSTYT\HwbHgFU*pVTKQ^YUPrQ=?q^S+A>MSbYVu\T) [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1407/ccs/fwd np:i:5 rq:f:0.987519
- AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGCTACTTATGAAACATGAATGGTCGGTCTTGTGGTCGCTTTTGTCGAAATCACCGGAAACATTAAATCAAAGAAGTTTATCAACCAATTAGTACAGTGGCATGTTAAGTAAAACAGAAAGAACGCCAAGTGGCAACAAATGACGTAATTATTTAAGCAAAAAGCGTAAACGCTTACAAAGGCCTATTTAAATATCAGTAAATCGTTGGAAATTGGGGTATGTGCTGCCTTCATACGCAAAAATGGATGCGACAGAAACGAGTTGTATGGCCTCCCACTACGCTCGCCTGCCGCGGACCCTAAAACGACAGTCGTTTGCCCAACTACGGCTACCGGCATCGCTCAGAACTTCGGGTCTTGGCCCACCTTTCTGACGCCTAGTCAACGTGCGTCGCCTCAAGTCCTTGGACAAAAAGAAGAAATATCAATTGCAAAAATAACTATAGGTACTTCTTTGAA [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1407/ccs/fwd np:i:5 rq:f:0.987528
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGCTACTTATGAAACATGAATGGTCGGTCTTGTGGTCGCTTTTGTCGAAATCACCGGAAACATTAAATCAAAGAAGTTTATCAACCAATTAGTACAGTGGCATGTTAAGTAAAACAGAAAGAACGCCAAGTGGCAACAAATGACGTAATTATTTAAGCAAAAAGCGTAAACGCTTACAAAGGCCTATTTAAATATCAGTAAATCGTTGGAAATTGGGGTATGTGCTGCCTTCATACGCAAAAATGGATGCGACAGAAACGAGTTGTATGGCCTCCCACTACGCTCGCCTGCCGCGGACCCTAAAACGACAGTCGTTTGCCCAACTACGGCTACCGGCATCGCTCAGAACTTCGGGTCTTGGCCCACCTTTCTGACGCCTAGTCAACGTGCGTCGCCTCAAGTCCTTGGACAAAAAGAAGAAATATCAATTGCAAAAATAACTATAGGTACTTCTTTGAA [...]
+
- QlRNXNPFlV+T8<g<QNYRZQYYN5MbeLRYRNXCL;jXXR4cNMVXO([O3hSJFnYNMlRYFmYNRN5kkhRYL;4bNUMR0M5V.RQLCLk7iiXM*hgQIP<Dj[.VL6L at i8fIiYRYUJW<WFkNT'9Kg:g;V'hhgMPH<`RL at U8Q@j;iRYD[5LhM7OcXRYMNMJNJeC6^hJNRK6MFOaP7IKCkM%K9LiTF.eI=P0^N->j]=LQOGQ:>OQEikYNRMl5J6LX1O$ff??AU<U<LVN(35\I+CWDH70ZhigU-CG<P69BIN,AiU/2A?;TQRDV3H7OT&???5I;4L/;7<BXW==^KEBJ<(OGH$?I59;6$K;F.M?^hQ'ILCG.S?95G8=.$ABOL>EHLJMLCQJhHMgN?mmSNIO3e9eMQ(R-GNGBK;D0=dM<H<9BSIRW<MQAMR;JM9-LRY%:=fFkTI(g\QRKEQM8TTYSXN:]8ZN61gkjeW?K<WDYYG]SFN=jM:hkR>h [...]
+ QlRNXNPFlV+T8<g<QNYRZQYYN5MbeLRYRNXCL;jXXR4cNMVXO([O3hSJFnYNMlRYFmYNRN5kkhRYL;4bNUMR0M5V.RQLCLk7iiXM*hgQIP<Dj[.VL6L at i8fIiYRYUJW<WFkNT'9Kg:g;V'hhgMPH<`RL at U8Q@j;iRYD[5LhM7OcXRYMNMJNJeC6^hJNRK6MFOaP7IKCkM%K9LiTF.eI=P0^N->j]=LQOGQ:>OQEikYNRMl5J6LX1O$ff??AU<U<LVN(35\I+CWDH70ZhigU-CG<P69BIN,AiU/2A?;TQRDV3H7OT&???5I;4L/;7<BXW==^KEBJ<(OGH$?I59;6$K;F.M?^hQ'ILCG.S?95G8=.$ABOL>EHLJMLCQJhHMgN?mmSNIO3e9eMQ(R-GNGBK;D0=dM<H<9BSIRW<MQAMR;JM9-LRY%:=fFkTI(g\QRKEQM8TTYSXN:]8ZN61gkjeW?K<WDYYG]SFN=jM:hkR>h [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1407/ccs/rev np:i:4 rq:f:0.990503
AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGCTACTTATGAAACATGAATGGTCGGTCTTGTGGTCGCTTTTGTCGAAATCACCGGAAACATTAAATCAAAGAAGTTTATCAACCAATTAGTACAGTGGCATGTTAAGTAAAACAGAAAGAACGCCAAGTGGCAACAAATGACGTAATTATTTAAGCAAAAAGCGTAAACGCTTACAAAGGCTATTTAAATATCAGTAAATCGTTGGAAATTGGGTATGTGCTGCCTTCATACGCAAAAATGGATGCGACAGAAACGAGTTGTATGGCCTCCACTACGCTCGCCTGCCGCGGACCCTAAACGACAGTCGTTTGCCCAACTACGGCTACGGCATCGCTCAGAACTTCGGGTCTTGGCCCACCTTTCTGACGCCTAGTCAACGTGCGTCGCCTCAGTCTTGGACAAAAAGAAGAAATATCAATTTGCAAAAATAACTATAGGTACTTCTTTGAAGAAACC [...]
+
@@ -351,10 +352,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGCCAACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGACAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGGTTTGCACTGTTGACCACCAGCACGCAATCGCAAGATACGCAGTAATGCTAAACCATAACTTATTTGACTTTGATGTTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGCTACACATATGCTGTTGGGAATTGTTTTTTACA [...]
+
Rz[RbIfJaA\SK;TL?OGULZc7P$ZVQSadYY]chnrrssssssssssssssssrZY6u$ACZ\AHB{Wu]Ybd1qQf at mRKvvfRXvRaQ?qF`N;,$M?XTB3WN`a[Sv`UZ`Cce<6D=8P>J0a`ZCgFQ`];ZN6]H_rfRIB:_N?UmZRaNQBgMY=.raJBfJYBtc=YeYLNFR5OaX`_[RAdcVNV2qP[QAJYK_MHC6GM'%@LSW at rI=YM[TTI3BXKY_:X_XC]c_FE|bXvRWt8ydZCtR_LKQ[VwbY.\ZfbZ2rKvXv7C0V;1qYb>]VNV<ZrVNXcALUA^ACsVK^:<uGkWFPaRfZHvZbDh7DsLY=[)2=>VXEZR6l[T^A<?$PZd.YcZOL/n[3\JN%*7EeM;rYB`QAuqU35Q'nSM;BKC]Dd5tgTkKx_RAxeF;_[O]_4YKYbRA_rvb[fR[LUTXRbQAlMVP3rP5oMmN]aRbRbfbeA'IYTt<q^J]0DA4hVgudNPL [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1549/ccs/rev np:i:6 rq:f:0.993149
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGCCACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGGTTTGCACTGTGACCACCAGCACGCAATCGCAAGATACGCAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGCTACACATATGCTGTTGGGAATGTTTTTTACACTTATT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1549/ccs/rev np:i:6 rq:f:0.993243
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGCCACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAATAGCCATTCTTCCTGAAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGGTTTGCACTGTGACCACCAGCACGCAATCGCAAGATACGCAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGCTACACATATGCTGTTGGGAATGTTTTTTACACTTAT [...]
+
- CgRHSSNEcKQd]Yw^SGd<*L0BE%clbVPOX\bltvvumc]ZZ_hruvvtk_[enD><sg]SO\c<uUxfTOJO_TE7q[BwwbGRd]OGTnOzh]SGEq>cNvfPd=NN__T<LYcHwSFDHZb0V\P>vU\gO\SN:uAvv`Zhb<r\:vbO\gXX;sFv[-trOLXPRDrH[R^TcF`;eZ^bXgT\.zs7EROWYFWOwTKO[V`Z5UMOQWOgGxg]@[dSw\OMxdTh]ThTYv9eTPzhRW[OS<h6P$sEeeh]T0q[S3uRMfS7S7`;Q at Q:S]OuTd\Of]g?wjNaLOPZ;SVN:cIWFaEg=mXQ\bT]P5QKJ^cLuhU[QFS[4uM[RXXfTheh\@W:JOFuKAG`Aws9pVdhLSw^<_sTh]9tH6K`S2p[bgbYOYM=dn&34XbTCR7RCOQZ^IK_`PhZBauq[SLSU[OA?EKYFZZ;RAt\G^2q at Kf]h\P:UPTZJ9E=7XfJib at +hm\^OHVBX0]d>d [...]
+ CgRHSSNEcKQd]Yw^SGd<*L0BE%clbVPOX\bltvvumc]ZZ_hruvvtk_[enD><sg]SO\c<uUxfTOJO_TE7q[BwwbGRd]OGTnOzh]SGEq>cNvfPd=NN__T<LYcHwSFDHZb0V\P>vU\gO\SN:uAvv`Zhb<r\:vbO\gXX;sFv[-trOLXPRDrH[R^TcF`;eZ^bXgT\.zs7EROWYFWOwTKO[V`Z5UMOQWOgGxg]@[dSw\OMxdTh]ThTYv9eTPzhRW[OS<h7Q&rGGfeh]T0q[S3uRMfS7S7`;Q at Q:S]OuTd\Of]g?wjNaLOPZ;SVN:cIWFaEg=mXQ\bT]P5QKJ^cLuhU[QFS[4uM[RXXfTheh\@W:JOFuKAG`Aws9pVdhLSw^<_sTh]9tH6K`S2p[bgbYOYM=dn&34XbTCR7RCOQZ^IK_`PhZBauq[SLSU[OA?EKYFZZ;RAt\G^2q at Kf]h\P:UPTZJ9E=7XfJib at +hm\^OHVBX0]d> [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1608/ccs/fwd np:i:10 rq:f:0.998309
AAGCAGTGGTATCAACGCAGAGTACGGGGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGGACTATGGGACTAGTCGTCTTCGGTCTTACAAATGTTGCAATGCCCTGTGAGCTACTTATGAAACATGAATGGTCGGTCTTGTGGTCGCTTTTGTCGAAATCACCGAAGTGCGTATAATTGATGAACGAGTCGAAGTCGAAGTTGTTCAACAAGAGAGTTAGGTAGTGCCGCTTGAAAAAGTAATAGTGCAAATAAGAAAAAGAAGCGAAACGGCATTCGTTTAACAAAACGTCACATA [...]
+
@@ -383,10 +384,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTAATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACT [...]
+
mxPKr3NBoNfbi,qRUnzW~Xdir7jl~sU}@zyLX`]A~kCyuS|6~h-t_UXSZrXIvRs0a.LKhS4RsVic6~~~~q=z\W{I[UQC~JHaTL1pe7~eW^]{fRQFdWsf?~~xlJ;hU`:kkdqG}[pTXNd]7csSnS6_HTqU/wFzyV<ygPb1/TadThWeGyrcT?&cvWsKzJ~dWAxu>coUZ5U8iH<8UnTvWgXc]U=ytSt<XHzzyBvKV$sae>^Sw[UNyRR|VsAq^d`WN1azVvsWreRZ5a]BO||Xz[UXFbRq_haX`2[fcTW[C^Z^dWcTSKfbxLxJ~{sU2QC6qo[nHg7jbzDb^F{_EVAM`kPY4_M-:\gQxaBNnFzWXtEFfrVK||pLITWIxPc:mRRF^cn^oUfVbwDHu]Yk&POBtdVJv|w^SW%zzfnSMaPU85eSudseXexcW@^B2v?cTL2x`NOH~YFOOrDb^Hd;ucIa8LXqGyQsTNURLTVIsgFt_qUz0M [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1688/ccs/rev np:i:7 rq:f:0.996824
- AAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTA [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1688/ccs/rev np:i:7 rq:f:0.996883
+ AAAGCAGTGGTATCAACGCAGAGTACGGGGCTTAAATGTCGGGAAATTGGGTTTGCGCCGCCTTCAGGGGCAGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACT [...]
+
- '~R_Ih:J~xopbZ~aUMrzC_fscB~~Y at YyPe~sjaaS~~J~k3~Z~qA~~~c~Q~~T~O~^rAE9X8ioXRW}4~~~~_jZKY]L~juWx_>~|4;_WxK]o;~X>~p]}c~>r~na~P~lXF~~47?`Alb_q]y:~~|_iP~gJTBb~AZC\1ae^km?~Vq[BpdbvQN]U1~~\K\~f~~}F~gE~~|ymhV\Kgof`hY_o~w`k<neJ~XR:~~[5KXeF~`^~jn`~Q~ob~QJB~~pO{x`]VFULl_FUUSmY^T~~~oLh^>~Hpd0J<MlVnq~_v_v`k[}ikoQ~~^M~A~oa~PrTSsq^^jOnPP{_lLg~pM~D~~rd]^]vW~bf_Yp;_`U]Q=n~FoTjSeh]le=W.|x at D]li=~~_nM}r~~ojA~~~b`ba8I?1X=|~X~mgI~~jH`HookwRq?~~_v}`j\^~~y=~~^alj~vo^V~\vm`u}a[E~J]?V~km}LJ~/~{~b`s9y0~lGSc^:~N~o [...]
+ )~Sf`Jh:J~xopbZ~aUMrzC_fscB~~Y at YyPe~sjaaS~~J~k3~Z~qA~~~c~Q~~T~O~^rAE9X8ioXRW}4~~~~_jZKY]L~juWx_>~|4;_WxK]o;~X>~p]}c~>r~na~P~lXF~~47?`Alb_q]y:~~|_iP~gJTBb~AZC\1ae^km?~Vq[BpdbvQN]U1~~\K\~f~~}F~gE~~|ymhV\Kgof`hY_o~w`k<neJ~XR:~~[5KXeF~`^~jn`~Q~ob~QJB~~pO{x`]VFULl_FUUSmY^T~~~oLh^>~Hpd0J<MlVnq~_v_v`k[}ikoQ~~^M~A~oa~PrTSsq^^jOnPP{_lLg~pM~D~~rd]^]vW~bf_Yp;_`U]Q=n~FoTjSeh]le=W.|x at D]li=~~_nM}r~~ojA~~~b`ba8I?1X=|~X~mgI~~jH`HookwRq?~~_v}`j\^~~y=~~^alj~vo^V~\vm`u}a[E~J]?V~km}LJ~/~{~b`s9y0~lGSc^:~N~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1757/ccs/fwd np:i:6 rq:f:0.997228
AAGCAGTGGTATCAACGCAGAGTACGGGGCATACTGCAAGACTTGTAGGCCCATGAATTACCCGCTTAGGCAATGGGTAGACCTTTCCTTGCCGCGTGGAACAAACCGCCATGAGTGTTTTTACGTTTACGGTCGGCGACCGGAGTCACAGCGCGACCAACGGGGCCAGGCAAAGGCCCATAGGCTTTTCCATCGGCACCGCGACCGATTCCATCAAGTGTTAGGTGCAATCCCCATTCGGGACGGACACGCGAGAGCGTTAGTCCGGCGCGTGCGCGGGACTATTTAGCGAAGGTCGCCGATCGTTTGCCCGTAAAACTAACTGGCAAAAGCCTAAGTGCTGTTTCGGGTGCAATGGTATAACTTCCCACATTTAGCCGAATAGCGCCAACAGCGTTATTATTTGGAACCAAGCAGTGGGCGATGTCAGCGACAATTCCACTTTGGTAGAGGTCGTTCTTTTGTAGAAAACAATCTAACATAACTATGA [...]
+
@@ -427,10 +428,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGTTGGTTCGTACAGCGGTAAATGACTTGTTGAGTCTTGACGTCGACGACCAAAGCGACCACTTTGACCCAATTGCGAACTACTAAATCCTAAGCAAAGACTATTAGGTAGTAGCCAACTTCGTTAATTCCGTTCAGTACTTTTAAATTCTAACCGACCATCTTTCCGAGTTGCTTCAAACCCTCGTCCTAATGATTTACATCGAATAGAACGTCGTACAAACGCACTACTACATGGAATAGATTCTCTTGTCAAATCGTTTTGTTTTGGCTTTACCCTTGGTAACAAACTTCGACTACGTTCGTACAATTCAGAATAACCTCTACCTCGTTAATTTGAGTTAGTTCGTTAAGGGCTTAAGTAGTTATTTCTATGATAAGCACTAAATTGACCTTAATTTCCTCGACTTATTGTTACATCTCGATTTCCCTTGATAT [...]
+
4~{~~~~z~~~~~~~~~~~~~~~~~$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~i~x~y~~s~~~~~pS~~J~~~s~~h~~{~u~~Mwd~h{~~~~~q_~~W~1~~~~~ob~~ps~~~~a~~~~v~`~~L~~s~~~a~~~p~~~~Z~n~~~~~|br~ke~~~~~~e/pl~~r~~et~s~~~j~~~~~k~z~~9~~~f~~f~~~s~QnW~~~~~~`~~n~~~~~~~~}~cb~n8~~~~hme~rfe~~~b~~~~~~~ln~Z~~{~~i~~~_~~g~~~~d~~q~~~~s~~h~`~~~~~q~~~~y~~~~t~~~~hK~~~zW~~~b~~a~~~q~~d~}~~~~~y~~~z~~~~c_~~~V~qsT~a~~~~~~~t~s~~a~~~~~i~~~~s~~~i~~~~~~~~~~~~~~~~~a~~u~~~~~e~~~~~d~~~~~x~~~~~~~~~~x~~~~~~7~~~~~T~~V~~~~~~~~~l~~~~~u~~~~~~~f~~\~~j~~~~~~ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1948/ccs/fwd np:i:9 rq:f:0.998158
- AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGGCTTGTCCGCGAGTGTCAACCGGGTTTTACAAAGGAGAACTTCCAACATCAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTACAAGAGTTGGTTACTCTCAGTCCCATTCCCAACACATCACTGAGAAGTATAGAGCCTAGTGGTCATTAGAAGGTCAACATGGAGTAGGTGTTTAGGTGTGTCGGAGGGCAGAAACCAACGAAAGAAAGGAAACGATCAACACTTATATAGTGTCCTGTCGGGCCCAAATCCTAAGAGACCTTAGGTTTACCACATTAGTAACTAAACAGCCTGTTGTATACCGTGAGCCCCCACTTCGATCTGTAAATGGTAATCCCTTGTAAAACCTCATCTCCAAAAACAGTATACGCAGGTACAGCTGATGTGATCCTCTCT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1948/ccs/fwd np:i:9 rq:f:0.998231
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGGCTTGTCCGCGAGTGTCAACCGGGTTTTACAAAGGAGAACTTCCAACATCAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTACAAGAGTTGGTTACTCTCAGTCCCATTCCCAACACATCACTGAGAAGTATAGAGCCTAGTGGTCATTAGAAGGTCAACATGGAGTAGGTGTTTAGGTGTGTCGGAGGGCAGAAACCAACGAAAGAAAGGAAACGATCAACACTTATATAGTGTCCTGTCGGGCCCAAATCCTAAGAGACCTTAGGTTTACCACATTAGTAACTAAACAGCCTGTTGTATACCGTGAGCCCCCACTTCGATCTGTAAATGGTAATCCCTTGTAAAACCTCATCTCCAAAAACAGTATACGCAGGTACAGCTGATGTGATCCTCTCT [...]
+
- c~zJVQmW~~X~QI~h~ghxozrAfM~~~lh~e~fS~}~B~~e}mxFz~gX~@~[~~=~~ySiL~~^~hwL~gh~R~h~fyximq~i~m~U~~~~kf~~g=~}a].x~~wl|l}}_c~~~vVh~\V{~R~X~~ekPt~mh~b~~~c~h~zT}7zaaq~cSQM{FZ~clwW~Q~{mcg~{hcO~i~h~~g~Mqj~~~I~~~V~<~qX~g}i|~YUX~d|ig~}~eUppcsQ~~{x~h~~>\_~ZkX~f~yhd~h~~d~Tg~X`x|OE~~kb~~|~i~Wh~oZ~~i~}X~{F~X{gkQ~~}B~~c~[~~j~{^gl~T~ie~ffin}z~~~2~~i~[I~lG~~G~~~F~x]~~m}mP~i~Xe~Z~~U8~}e\e{m}w<~j~:~pc~{2~~z^~y}~l^W~~~~|x4~~~s[iw~ceh~hu|pMg|~R~wR~~C~~q~s}?~oUHheNe~c~R~)~~~PMxtmw~P=u`t`~~s^pGb~]9Xvq`yuN~n`wLf [...]
+ c~zJVQmW~~X~QI~h~ghxozrAfM~~~lh~e~fS~}~B~~e}mxFz~gX~@~[~~=~~ySiL~~^~hwL~gh~R~h~fyximq~i~m~U~~~~kf~~g=~}a].x~~wl|l}}_c~~~vVh~\V{~R~X~~ekPt~mh~b~~~c~h~zT}7zaaq~cSQM{FZ~clwW~Q~{mcg~{hcO~i~h~~g~Mqj~~~I~~~V~<~qX~g}i|~YUX~d|ig~}~eUppcsQ~~{x~h~~>\_~ZkX~f~yhd~h~~d~Tg~X`x|OE~~kb~~|~i~Wh~oZ~~i~}X~{F~X{gkQ~~}B~~c~[~~j~{^gl~T~ie~ffin}z~~~2~~i~[I~lG~~G~~~F~x]~~m}mP~i~Xe~Z~~U8~}e\e{m}w<~j~:~pc~{2~~z^~y}~l^W~~~~|x4~~~s[iw~ceh~hu|pMg|~R~wR~~C~~q~s}?~oUHheNe~c~R~)~~~PMxtmw~P=u`t`~~s^pGb~]9Xvq`yuN~n`wLf [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1948/ccs/rev np:i:8 rq:f:0.995017
AAGCAGTGGTATCAACGCAGAGTACGGGGTGAGGCTTGTCCGCGAGTGTCAACCGGGTTTTACAAAGGAGAACTTCCAACATCAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTACAAGAGTTGGTTACTCTCAGTCCCATTCCCAACACATCACTGAGAAGTATAGAGCCTAGTGGTCATTAGAAGGGTCAACATGGAGTAGGTGTTTAGGTGTGTCGGAGGGCAGAAACCAACGAAAGAAAGGAAACGATCAACACTTATATAGTGTCCTGTCGGGCCCAAATCCTAAGAGACCTTAGGTTTACCACATTAGTACTAAACAGCCTGTTGTATACCGTGAGCCCCCACTTCGATCTGTAAATGGTAATCCCTTGTAAACCTCATCTCCAAAAACAGTATACGCAGGTACAGCTGATGTGATCCTCTCTA [...]
+
@@ -455,10 +456,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTGACCCAAATAATTAACTCGTTCCAATAGTTGAAGTGTTGATTAACACATTGAGACAAGTTGTCCGTACTTTAATCATCAAAGTTTTGGACTGACCTATAAATGAAATATTCGCGTTGTCTTCAGTTTAAGAAGTGATATTATTTTCGGTTTCAAGCCTATGTGGAGAGATACAGGAAATAGGTAAACTATAACTAATATAAATATACGCAGACGAAGCCTGTTAACTTTACCAAATCCAAATAGCGGGAGACA [...]
+
W~e]henC~hbp\H~\_MZcRcnOE=~~~pCucWd6hVbkK~7TIdMhheZEHEG_mFcpeU`4Y3zRA~fW6xcd]lMX~[YY_H8>J]>ch>~sZ=VIXPm\EkZFjwcmcaR`JI`WfV_nFdTt-cu_[c/c_^epUn__`~OI~\ep]KjeA~`P~PLc;NW;,%VdOX0>3eJk9ZLbR\gYIBI6BbheL~~~[>ne`~Md?X_n)rmWcheh[Z=UHNYVMJC(B`cWddR9~\@~~oX~'$$zBn]e[g>oKmhLcBPQ/vPlMVB`VU~7|ZQ\fM~O;AH\+LL_~ELL~emIUCzXCw_\eV[F~nM1w_sA~f\i]^-`[\_2~bUc3~f_'Ta2]]a5}HQXVu]Mc6b~Sd_0xaUcglgYnR=VYq\QwF~jF2/MM~nQUcnCud;cSRl:XO1f0z[OfQ~_8nmYUeiFk]pK~nK^LycoeSMCL[idhZMRsd<~lLHzJ~]R~lXL~>~oOJm:97jbcE6i`GR]CL [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1999/ccs/rev np:i:5 rq:f:0.994586
- AAGCAGTGGTATCAACGCAGAGTACGGGGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTGACCCAAATAATAAACTCGTTCCAATAGTTGAAGTGTTGATTAACACATTGAGACAAGTTGTCCGTACTTTAATCATCAAAGTTTTGGACTGACCTATAAATGAAATATTCGCGTTGTCTCAGTTTAAGAAGTGATATTATTTCGGTTTCAAGCCTATGTGGAGAGATACAGGAAATAGGTAAACTATAACTAATATAAATATACGCAGACGAAGCCTGTTAACTTTACCAAATCCAAATAGCGGGAGACACT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/1999/ccs/rev np:i:5 rq:f:0.993133
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTGACGATCCCTGAGACTATATCATACAAAATTGACCCAAATAATAAACTCGTTCCAATAGTTGAAGTGTTGATTAACACATTGAGACAAGTTGTCCGTACTTTAATCATCAAAGTTTTGGACTGACCTATAAATGAAATATTCGCGTTGTCTCAGTTTAAGAAGTGATATTATTTCGGTTTCAAGCCTATGTGGAGAGATACAGGAAATAGGTAAACTATAACTAATATAAATATACGCAGACGAAGCCTGTTAACTTTACCAAATCCAAATAGCGGGAGACACTA [...]
+
- <aOGW[]-lfnQd`~MXFEP^Ygj_:~|_aF^Z`X8ycj_U~KrM[Zgi`FahEAaNZ>GA;;>S%m)]adCyoQa:[a~]pcFcVl=no]m&|h8MhQ~X~`Z~S5cXIdEfJBj6uKne\RL~NrDz`g`U8xuQ[h]rT5MagAfJEdM[tg>~f?|hnQS|Wg^M~dcHiOyX~]gL~2i`hlLDc\pe[OR1XgwdnLRM at Hne]nJI~~bT:VneaLeohephp_0[byX~]pEsWD{~e`}bC{~Lfe]KgC~a~hp[$DFNvJY@'CGdBEH_^peoG~XiYc\0YDLcAbR~[;md0qh\gddf&`G~yX5pSnN}SKg]pU~hhRE~qR[J~~feImdZ`\@J[ca&apX8[F=uY:GQ;YUQl5nd1jJ7EFAZzeb~WP|c:_EaCg8,ODdKi5kO~2~shp:\:2xsQGmhZaZZGb\TQDnuhphjcG[nFkMZL~EO}\/6qIg]@~~oQ}Q|lRQ~GZyfk\e*~rhSjepec [...]
+ <aOGW[]-lfnQd`~MXFEP^Ygj_:~|_aF^Z`X8ycj_U~KrM[Zgi`FahEAaNZ>GA;;>S%m)]adCyoQa:[a~]pcFcVl=no]m&|h8MhQ~X~`Z~S5cXIdEfJBj6uKne\RL~NrDz`g`U8xuQ[h]rT5MagAfJEdM[tg>~f?|hnQS|Wg^M~dcHiOyX~]gL~2i`hlLDc\pe[OR1XgwdnKP%Bme]nJI~~bT:VneaLeohephp_0[byX~]pEsWD{~e`}bC{~Lfe]KgC~a~hp[$DFNvJY@'CGdBEH_^peoG~XiYc\0YDLcAbR~[;md0qh\gddf&`G~yX5pSnN}SKg]pU~hhRE~qR[J~~feImdZ`\@J[ca&apX8[F=uY:GQ;YUQl5nd1jJ7EFAZzeb~WP|c:_EaCg8,ODdKi5kO~2~shp:\:2xsQGmhZaZZGb\TQDnuhphjcG[nFkMZL~EO}\/6qIg]@~~oQ}Q|lRQ~GZyfk\e*~rhSjepec@ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2012/ccs/fwd np:i:6 rq:f:0.993131
AAGCAGTGGTATCAACGCAGAGTACGGGGCTTGTCCGCGAGTGTCACCGGGTTTTACAAAGGAGAACTTCCAAACATCAAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTGTGAGGCGCAAGGTACATGCTCTTACCCCACTCTCAGCACGTAGGGAGCGGAGTGTGGAAGACAACAAGCCCGTCGCCTCTACCAAATACAGCTATCCTGAGGTGCCAGGTTAGAATAGGCCCTACCACATCTAAGCCTTGAAACGGTCTGTTCCTCGTGTCAAGTTCTTGTCCGCTTATACCGCCATCTCTCGTTGTGGTACAAGAGTTGGTTACTCTCAGTCCCATTCCCAACACATCACTGAGAAGTATAGAGCCTAGTGGTCATTAGAAGGTCAACATGGAGTAGGTGTTTTAGGTGTGTCGGAGGGCAGAAACCA [...]
+
@@ -495,10 +496,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGACGCAAATGCCACCAATACATATGTGTCCTCTTAATGTTTGCATGCTTAATTCTTTTGATTATTATTTCCTCTTTCTTTCTATTACTAACTTTGTAACTCTCGCTAACCGAATCAACATAAATACGTCAACGAATCAAATGTTGATCTCAAATATCTGTGTCCATGAAATTTTCGGATCGTAATCTGCTCTACTTTTGTTATTACAACAAGAACTTCGACTAAAGAACGGACTATCTTGTCTAATAATAATGGCACTAAGTGCATACTTTCTCGACTACATTGACGACTCAAAATAAGAAAGGGAGTTTTTATACATTGACCTAACTCACTACTACGCCCTTGGTTACCTTTGAACCTTTCGTTGTCAAAGTTCGTACGATGGTAAGTGCTTTCTTACTCCTACCGCTATTTGGTTGAGAACCTGTTAAATGA [...]
+
p~y]httc~jM~\8zdfZ|xix~Nh$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``ZRw\@~~~yM~yZ~G~~zp~~h~mlx~X~j]Y~F~~yZ~~xVuj_YF~e~%lq@~~~rRc~~f~}I~~a~~lY~~sY~~mQb_~{niI~ra~cred~m|t{Oqn~Y~Xk^T~|j1qYul?~~htih^bNzaiJn(a7ys\gH~nnE\pa/|~|s|iyWzozH~h$c'T76~~u`6gn_gWwS~ycuodGc^PM<~~~mU~r`z at B7q_[~o=zbK~UPmfx)~~lN~S\~]hy]Y_b~jse]W~_S~\T~{]~hrcp.~jtR`VrmT]~~QxbjpNyqWTY~m]Wm[M[\0pTWpZhn?~nR~~snD~~~rDrXcsg~n]NlXN~Y<O:ZLDTx\ad&tWW~\~W~]U~Kh}VM~OZ1uoSb<~`IeNymgT~dl|djk)CZ~f1|j\hG9~~<+3/d{T~t]<`/bWm0~xIxO~gTi\~W~|nV~C~t]ms [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2164/ccs/rev np:i:7 rq:f:0.996833
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGACGCAAATGCCACCAATACATATGTGTCCTCTTAATGTTTGCATGCTTAATCTTTTGATTATTATTTCCTCTTTCTTTCTATTACTAACTTTGTAACTCTCGCTAACCGAATCAACATAAATACGTCAACGAATCAAATGTTGATCTCAAATATCTGTGTCCATGAAATTTCGGATCGTAATCTGCTCTACTTTTGTTATTACAACAAGAACTTCGACTAAAGAACGGACTATCTTGTCTAATAATAATGGCACTAAGTGCATACTTTCTCGACTACATTGACGACTCAAAATAAGAAAGGGAGTTTTTAATACATTGACCTAACTCACTACTACGCCTTGGTACCTTTGAACCTTTCGTTGTCAAAGTTCGTACGATGGTAAGTGCTTTCTACTCCTACCGCTATTATGGTTGAGAACCTGTTAAATGAGATGG [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2164/ccs/rev np:i:7 rq:f:0.996992
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGACGCAAATGCCACCAATACATATGTGTCCTCTTAATGTTTGCATGCTTAATCTTTTGATTATTATTTCCTCTTTCTTTCTATTACTAACTTTGTAACTCTCGCTAACCGAATCAACATAAATACGTCAACGAATCAAATGTTGATCTCAAATATCTGTGTCCATGAAATTTCGGATCGTAATCTGCTCTACTTTTGTTATTACAACAAGAACTTCGACTAAAGAACGGACTATCTTGTCTAATAATAATGGCACTAAGTGCATACTTTCTCGACTACATTGACGACTCAAAATAAGAAAGGGAGTTTTTAATACATTGACCTAACTCACTACTACGCCTTGGTACCTTTGAACCTTTCGTTGTCAAAGTTCGTACGATGGTAAGTGCTTTCTACTCCTACCGCTATTATGGTTGAGAACCTGTTAAATGAGATGG [...]
+
- X~\xjquU~PP9sH~\V6L>gp~~|&~~~~~~}tz~~~~~~~~~~~~~~~~~~rrkuqv3~~}tJ~YVg8~cydefJ[Ly`{f~~xZ~T~}mH~dGO2;Lj_~W~wtGqf~t~P~~i~~Y~~`~jtH~~vV~~xI0A}~{jZ~p9~~l}5~\;adLj^i+SRk)@;Azs~yjgU~~;}a:_r:~x_v~~{L~xQrK~r~[s{u1~}Kcx||WZUKZ~ui\V~~H~~uZ~~|vl_Zzyv{bW=kZev<~~aK8maU~~s9~ab~[a~{K~z]mvp7{~qr~j>~j{~oh{N~pPsjk~pf~[S~WU~c~{j[~i}Hswghm4~~jig0'Y`kwiLzZ]qdJ[Kx=~~qcZ~V:~~S~~Np;~~~oJoqLw~T~o|=~cv~{irhzR~wwi`kY~R~[~A~g~X~bkm~_iF~~roNw\hdi~~p\~vWubpS~~Z}Mu~r|rxM~~|~pxhN~NlR~lmKbOE+SOy^{dYj4~_~oGB~F~~yi=[ExS~ [...]
+ X~\xjquU~PP9sH~\V6L>gp~~|&~~~~~~}tz~~~~~~~~~~~~~~~~~~rrkuqv3~~}tJ~YVg8~cydefJ[Ly`{f~~xZ~T~}mH~dGO2;Lj_~W~wtGqf~t~P~~i~~Y~~`~jtH~~vV~~xI0A}~{jZ~p9~~l}5~\;adLj^i+SRk)@;Azs~yjgU~~;}a:_r:~x_v~~{L~xQrK~r~[s{u1~}Kcx||WZUKZ~ui\V~~H~~uZ~~|vl_Zzyv{bW=kZev<~~aK8maU~~s9~ab~[a~{K~z]mvp7{~qr~j>~j{~oh{N~pPsjk~pf~[S~WU~c~{j[~i}Hswghm4~~jig0'Y`kwiLzZ]qdJ[Kx=~~qcZ~V:~~S~~Np;~~~oJoqLw~T~o|=~cv~{irhzR~wwi`kY~R~[~A~g~X~bkm~_iF~~roNw\hdi~~p\~vWubpS~~Z}Mu~r|rxM~~|~pxhN~NlR~lmKbOE+SOy^{dYj4~_~oGB~F~~yi=[ExS~ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2225/ccs/fwd np:i:6 rq:f:0.995244
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGTAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTTCGCAATGAAAAGAATATCCTTATAGACACGAAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCT [...]
+
@@ -519,14 +520,14 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCCTTCAACAATTTTACAAAGCAATGCTTGTGGGCTAGGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAAATTTACGGTGGTAATTTCGCACACTTCG [...]
+
e~b]k^bS~gZeY9jW^Ll`X^MUY$W_kyyrmlnpaWSV`igiowuqqu}~~~|kgZcSd`/V@\^lP~i@(9IC>QMYdLkS~fHeK~bkVkfN~lYX7z`YWd@~~A~k]dG=H~KJ~N|fFWU:|^7L9~xSj]d[[Ca[BlV5bmDP~mbfmba^$~~~~~\]]E~O~MT).,_j6rb^dWZcX`L~jPZKDj[UILYtXGXC.~~oALLn_D~V)}PI}]CfJUo<~~~l\2{g_\M~ec]X~WRD~f4eVG~i3U(S^Za;|iy^6\[d?~}KjbmeaNAlN~`A<iX7]LVK0y~\fb]f]b3 at G@j1~WJiaM~]bdH``E_:|G{\2lq~fWejeZAEdY~[bfbfm8xfj;mOwXLWa]bN~a2u2ey_PfJjeZfWZf_kL~~]fX.oebflN~~P<=~c1jXb]f]hb\FaJEaFbYMZW~bjOJ3`hVwIYkH@~z^g^eg=h(CY)RRL~~lZ-}dRy`7yBrvPH[SYgHUo]` [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2286/ccs/rev np:i:7 rq:f:0.996434
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTTGTGGGCTAGGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAATTTACGGTGGTAATTTCGCACACTTCGCACG [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2286/ccs/rev np:i:7 rq:f:0.996436
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTTGTGGGGCTAGGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAATTTACGGTGGTAATTTCGCACACTTCGCAC [...]
+
- :RH at PCW;qnhncG~[_deZi\nhc%~tc_gmnmnniefmu{mQ at 8;IbxsiYST\LcRdfdne]Yf?}gd_nai@~gep^QO~i`PO}Ga`aYO~SbhR~nh^Y;~eP~fNWbhU~_N|U~YeNfQ~JWt>zdL~`:Z\XPNJ~MQy~bHf]^;E_n\+Wx~~jbDJdJ~C`,~CfO&O_KfQ_fiXT~fVa_XpaRW]M~_N~c at gs~h`T~VDdM?VWiMW~dX~>~~Q:KBjfI4D~kJbYs\f%uoWad;~ua<Pq_c]=jfsIV~JWP~~nh]dm^YW~C~mhU~g;wcOQ=~~am_dncYG~cW~9~~U~\O~[NWc^Y`5Kx,^K5U[QZ\\HG7UUhTsaGB[egR~oiR~VQgXR?7F]~jR~'~[[TgefXekQO`_]H]{_ndX~n_l8CvvZhQlYK~`j_ncY^bXlncncT^XbX~PclQc^YY~JXia?kvXM]nhNqhd_X~Bqq_L>mZ<x^Tg>zj_^Nfchb4fD^ahK] [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2295/ccs/fwd np:i:4 rq:f:0.992925
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTAGTCTGGCAGATTAGATACAGCTATAGAGCGAATCACCACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGTGGTTTGCACTGTTGACCACCAGCAACGCAATCGCAAGATACGCAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGC [...]
+ :RH at PCW;qnhncG~[_deZi\nhc%~tc_gmnmnniefmu{mQ at 8;IbxsiYST\LcRdfdne]Yf?}gd_nai@~gep^QO~i`PO}Ga`aYO~SbhR~nh^Y;~eP~fNWbhU~_N|U~YeNfQ~JWt>zdL~`:Z\XPNJ~MQy~bHf]^;E_n\+Wx~~jbDJdJ~C`,~CfO&O_KfQ_fiXT~fVa_XpaRW]M~_N~c at gs~h`T~VDdM?VWiMW~dX~>~~Q:KBjfI4D~kJbY~\f%umaXjg:~ua<Pq_c]=jfsIV~JWP~~nh]dm^YW~C~mhU~g;wcOQ=~~am_dncYG~cW~9~~U~\O~[NWc^Y`5Kx,^K5U[QZ\\HG7UUhTsaGB[egR~oiR~VQgXR?7F]~jR~'~[[TgefXekQO`_]H]{_ndX~n_l8CvvZhQlYK~`j_ncY^bXlncncT^XbX~PclQc^YY~JXia?kvXM]nhNqhd_X~Bqq_L>mZ<x^Tg>zj_^Nfchb4fD^ahK [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2295/ccs/fwd np:i:4 rq:f:0.992462
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTAGTCTGGCAGATTAGATACAGCTATAGAGCGAATCACCACGTCTCCTTAGATAACTGGCAAATCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTGCACTCCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGAGTGCGAAGCCACTAGTGGTTTGCACTGTTGACCACCAGCAACGCAATCGCAAGATACGCAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGC [...]
+
- S_GKVGB?[TFSL,ZRKRFJ[KR/B$PV_ddddb\WTSRNKJMRVXMIKPTLHNWU3M:T=fKCJZEcGJ\VU9X6O>YTEIEJSKLaGS\E\@@FLNQ2\IeFISD>cSV at mR6d_FSKfP.;NeJfFO7B at N;\EdFUYLMfV\I=4bU at dKQ1RAI4deJEXHFZTQ5ZFd>RSS;DU?lR/_F9=DJUEc;bP4EKJE`VKNfTR;V;R8CA*CU\UFJQ%_HI=I9dRK\EdBSAQREOVS[BFO=L7MH1F<ZKfS\FdVJD<IAF'^ZD8J4OUFGSJfFdVJ>cQADPRKKf\K>bKPEJH`>SJeOfVKSKfKVSVWGS<PVKC4=ISKM]G5bZNQZ7,2RBf^F9UGR%:L7V at _FFi\KR,D<H<NeVRJQ>XJAOUGJ<VKU:PUI:<9_P:VXTAMHf\CffK\SBf\F at TJ;cP<CTAH>D:eeEI:BSJ4aRF(SKQ=UDcVJWG8g[WQ:>O4<H\KSQQ>eRKL7QRJc1hR [...]
+ S_GKVGB?[TFSL,ZRKRFJ[KR/B$PV_ddddb\WTSRNKJMRVXMIKPTLHNWU3M:T=fKCJZEcGJ\VU9X6O>YTEIEJSKLaGS\E\@@FLNQ2\IeFISD>cSV at mR6d_FSKfP.;NeJfFO7B at N;\EdFUYLMfV\I=4bU at dKQ1RAI4deJEXHFZTQ5ZFd>RSS;DU?lR/_F9=DJUEc;bP4EKJE`VKNfTR;V;R8CA*CU\UFJQ%_HI=I9dRK\EdBSAQREOVS[BFO=L7MH1F<ZKfS\FdVJD<IAF'^ZD8J4OUFGSJfFdVJ>cQADPRKKf\K>bKPEJH`>SJeOfVKSKfKVSVWGS<PVKC4=ISKM]G5bZNQZ7,2RBf^F9UGR%:L7V at _FFi\KR,D<H<NeVRJQ>XJAOUGJ<VKU:PUI:<9_P:VXTAMHf\CffK\SBf\F at TJ;cP<CTAH>D:eeEI:BSJ4aRF(SKQ=UDcVJWG8g[WQ:>O4<H\KSQQ>eRKL7QRJc1hR [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2295/ccs/rev np:i:4 rq:f:0.976003
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTAGTCTGGCAGATTAGATACAGCTATAGGAGCGAATCACCACGTCTCCTTAGATAACTGGCAAATTCTTCACAATTACGCAAGACCATAGAATAGTCCTAAGCAACATTTGCCGCATCGACCAAATCATGGCTTTTGCACTCAACTTTGCCTGAATCGTGTCAGACTATAGCGGGACGTTCGACCATACTACTCATTCGATTACGCATTCACCTGACGAGAATAGCCATTCTTCCTGAACATACGTTAGAAGTAGTTGGTTAATGCTTGTCTACATTTGACGTGCGAAGCCACTAGGTTTGCACTGTTGACCACCAGCACGCAATCGCAAGATACGCAAGTAATGCTAAACCATACTTATTTGACTTTGATGTTCTATCACTGGGTTAATGCCTGCTGCTACCTGACTTTTAGTCGCGAGCACAACGCTTCTTGGCTA [...]
+
@@ -543,18 +544,18 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTA [...]
+
~~~~~~~a~~a~~f~|ge~{~}~u~%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}z_~zys~~}u~~~~~~}~d~}~~@~q~vb~~S~||~vd~gxz~~~~z_ty~y{|~~f~~}~~~~~f~c~d~cy~;~}~~V~~f~t~g~O~J~~u~Q~~fa~]~O~}F~~~{~~~Dq~~~~t~}~y~f~~,~~~~h~~zu~b~q~e~c~h~~~vdvG~~>~~~~{v|~~~~{~v~}~~uzx\{HUzxK~~~Z~~~h~rc~a~~T~~~~gU~~}s~~~~u~f~~a~|Z~~~{<~~J~~`~|M~~h~r~c~|R~~i~`~~Xsrfj'zya~~q~~}U~~~a~N~gY~~~`~~~g~<~mb~h~~v~`G~I~}W~~V~~~w~ze~~~~}{%~ld~~~>~~{~~~x~M~~h~I0|~hzd~x~B~~jz~l~g~~~|e~[~~~~~t~u{|W~~e~H~~~~U~b|~]~\}YO~~f~~~1~~~~~F~~~oK~ch~~g~~~~{~~r [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2319/ccs/rev np:i:10 rq:f:0.998414
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTAG [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2319/ccs/rev np:i:10 rq:f:0.998476
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCAAGTAATGCCTCTACGTCAGTCGGAACAATGTCGTCGTGTAACTCGACGATCTTAGGAGCTACTAAGGAGAGTCTGTAGGGAACCGACTGGAAGGTGCCACAAGTTTTCTCTACTACTCCGTCTCCTAAAACAACTCCAAGTGGAAGGTCTGTGGGTTTTTGAGTATAGTCCGTATCTAGACCCAAAAGGGCTTACCTTCGCAATGAAAGAATATCCTTATAGACACGAACGGGAAGAACGGAATCGTTATTAATGACGTCGTACAACGTTTTCCAAGTTCTCCTCTTCCTCCGGATTCGGTTTGGGTTATCTCAACTAGTCCTTTCAAAGACATTGGAGAGTTTCACCTTCCCGTTAAGGTAGAACCCTCAGCATGTTTCACCCCCGGTGACCACTCAGTTACGGAATGTTTTTAAGCCACCTCAGCTAGT [...]
+
- O~VSb~~a~t~u}|~~~Q~x{~C_z&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}y~~\b~~{G~~{~y{_~fxy~~e~W~hz~~o~|tg}~~~~U~}~~~~~~~~}g~~w~~~~a~z~W~c~~f~~w|~~~~c~~g~h~~~]~$~|MvR~={a~~fV~~V~~~{~wS~~~~}wb~uo~oc~~D~~~}g~}~g|S~~~d~\~q~u{J~~[~~>~~~~K~~~wE~~rc~~~xmx~~~{U~~T~~~K~~gh~~U~^~}~~|~~}W~~fw~~x~a~{{~t~}~~~~~{~|W~~S~~x~~h~j~~hwr~vS~{~uw~~~)q~~~~y~i~B~~~Z~{~~u~}Qe~~{B~S~^h~y~{t~|c~f~~G~~K~~~~~{x~~wy~~c~e~~RO~~g~~~o~b~g~t}O~~g~g~o~J~~~`~|~v~\vyc~G~~~~~}z~~d4~~fy/~~~sjh~}~U~~|sf~~w~xfR~T~~~,~~~~x~QT~~X~~}Ku}_~} [...]
+ O~VSb~~a~t~u}|~~~Q~x{~C_z&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}y~~\b~~{G~~{~y{_~fxy~~e~W~hz~~o~|tg}~~~~U~}~~~~~~~~}g~~w~~~~a~z~W~c~~f~~w|~~~~c~~g~h~~~`~%~LxR~={a~~fV~~V~~~{~wS~~~~}wb~uo~oc~~D~~~}g~}~g|S~~~d~\~q~u{J~~[~~>~~~~K~~~wE~~rc~~~xmx~~~{U~~T~~~K~~gh~~U~^~}~~|~~}W~~fw~~x~a~{{~t~}~~~~~{~|W~~S~~x~~h~j~~hwr~vS~{~uw~~~)q~~~~y~i~B~~~Z~{~~u~}Qe~~{B~S~^h~y~{t~|c~f~~G~~K~~~~~{x~~wy~~c~e~~RO~~g~~~o~b~g~t}O~~g~g~o~J~~~`~|~v~\vyc~G~~~~~}z~~d4~~fy/~~~sjh~}~U~~|sf~~w~xfR~T~~~,~~~~x~QT~~X~~}Ku}_~}| [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2333/ccs/fwd np:i:5 rq:f:0.992602
AAGCAGTGGTATCAACGCAGAGTACGGGGAATTTAGAGGCCATAGGTTATGGAAAAAGTCAGTGGATTAAGATAGTAAAAGTCGAAATCTTTATATTCGGTTCGATGTACTACGTTATTCGCGACTGTTCTGTCATGATAGTTTTTTATATAGTCCTAATAAAAGGAGTTTTTAAAGTAAATGACATTTCAGTAGTAAAAGTTTAAAGAGCTTTTTGTTCTGCCAGACGTTCTGATAGTTGAGGAAAACGTGTGGTCAGCTAATAACTTGTGGTATGGAGTAAACGAAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATT [...]
+
c~YLTIh?~krh]PxOZdYV[Xmsf4~wh6u?k~\ZrJ~RlYeWL~[~Fc;c9y~~qXUfqGkGsPTj+^ZakaZj)o`dXmgZI~~dPB~~mh_V^&J~M|eYYiYTmMZTZWK{EF~bVaXC9?WHsPlZkN[UYIefX/~p`pbDipkp[jCsWL|j7{u_H~ZE'ksn::ii at hE_g>IFTBAr`IPEdWVf)K'.@;no%W?E3Yf7~~~oZCoWm[FwUW0bGYlafY]krY[_YsI~BuwwQYlZk9~iP\XciNhj`~f]~WnG~g`lL~\Zm6~xfZ'tW]oYR~T|UrZkIhUcB;.2SNFX<ZM^LEdm4_]]I|~l^aX:sTSLYqgTG~nV]6~ZGXlQm1ycQmHE}~YnUVmXECdPqfZmb~G~Fs~lfY4t^SYh.dZsUj[7vfYSMMqaEjs=iVqgSzZI^N~e]erT~V~ZlP~\~ogQRXPDAMZsW<`pZ8+^Z5|DO\CDUE{~lZlX[b`G]FeNhVk6;_IZYe [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2333/ccs/rev np:i:6 rq:f:0.994191
- AAGCAGTGGTATTCAACGCAGAGTACGGGGAATTTAGAGGCATAGGTTATGGAAAAAGTCAGTGGATTAGATAGTAAAAGTCGAAATCTTTATATTCGGTTCGATGTACTACGTTATTCGCGACTGTTCTGTCATTGATAGTTTTTTATATAGTCCTAATAAAAGGAGTTTTTAAAGTAAATGACATTTCAGTAGTAAAAGTTTAAGAGCTTTTTTGTTCTGCCAGACGTTCTGATAGTTGAGGAAAACGTGTGGTCAGCTAATAACTTGTGGTATGGAGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTG [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2333/ccs/rev np:i:6 rq:f:0.994298
+ AAGCAGTGGTATCAACGCAGAGTACGGGGAATTTAGAGGCATAGGTTATGGAAAAAGTCAGTGGATTAGATAGTAAAAGTCGAAATCTTTATATTCGGTTCGATGTACTACGTTATTCGCGACTGTTCTGTCATTGATAGTTTTTTATATAGTCCTAATAAAAGGAGTTTTTAAAGTAAATGACATTTCAGTAGTAAAAGTTTAAGAGCTTTTTTGTTCTGCCAGACGTTCTGATAGTTGAGGAAAACGTGTGGTCAGCTAATAACTTGTGGTATGGAGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCCTGAGACTATATCATACAAAATTGA [...]
+
- 4VXVOZR=KC<%RVBkPZ>c^M^XeV9vr^Iq)X_cJ`Ln-XcN?rChLU/[50?d\MENMNZAJZD\HLPSaXV>`Y_^?T`LwwkVDslLOLEVSRw[uVa`aGKdU>]RXMdcNiLTJRRHTL7T at DA-HE3UGQQ=K9`defWegaOd^P9V<VvkEww_?sa[<[RTcKthRiMY^V[_26:NF>b^:KIPFfkgXAH]WqYIDR*^WF6:R)\UVH)xaJbA]*=:DBLbMG4aYM>rEvo\SOYNC5acVf`UUUrXXvWIt^QOuSdd;r`D<BvuU`VtBakGbBfUe_PbP^jfVXvkV`fVk`f`LmV?sdV;u]KU83TlCJ@^fkeLwe`e=vud^O8dEoUEs_Svv_U`fk``EWSfV_?SV+X(_LLOJNvvk`kYv]XYvbEURFgVXviA]dMiW_)UtJPVGoUeVeJyXv]PWvNwd9RV`UJdV`f`5vvdVffUNhD`,YWkB~oRM;5bViaXJPT8<TUDivtNx` [...]
+ 4VXVAZQ<EC=(UDjSX>c^M^XeV9vr^Iq)X_cJ`Ln-XcN?rChLU/[50?d\MENMNZAJZD\HLPSaXV>`Y_^?T`LwwkVDslLOLEVSRw[uVa`aGKdU>]RXMdcNiLTJRRHTL7T at DA-HE3UGQQ=K9`defWegaOd^P9V<VvkEww_?sa[<[RTcKthRiMY^V[_26:NF>b^:KIPFfkgXAH]WqYIDR*^WF6:R)\UVH)xaJbA]*=:DBLbMG4aYM>rEvo\SOYNC5acVf`UUUrXXvWIt^QOuSdd;r`D<BvuU`VtBakGbBfUe_PbP^jfVXvkV`fVk`f`LmV?sdV;u]KU83TlCJ@^fkeLwe`e=vud^O8dEoUEs_Svv_U`fk``EWSfV_?SV+X(_LLOJNvvk`kYv]XYvbEURFgVXviA]dMiW_)UtJPVGoUeVeJyXv]PWvNwd9RV`UJdV`f`5vvdVffUNhD`,YWkB~oRM;5bViaXJPT8<TUDivtNx`e [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2334/ccs/fwd np:i:10 rq:f:0.999086
AAGCAGTGGTATCAACGCAGAGTACGGGGTGGAGAAGCAAATACTTGGATACCGAATTTAGAGGCCATAGGTTATGGAAAAAGTCAGTGGATTAGATAGTAAAAGTCGAAATCTTTATATTCGGTTCGATGTACTACGTTATTCGCGACTGTTCTGTCATGATAGTTTTTTATATAGTCCTAATAAAAGGAGTTTTTAAAGTAAATGACATTTCAGTAGTAAAAGTTTAAGAGCTTTTTGTTCTGCCAGACGTTCTGATAGTTGAGGAAAACGTGTGGTCAGCTAATAACTTGTGGTATGGAGTAAACGAACATCCAACAGTATGTACAATCGTATGAGAAAGGACAAATCTGAAGACGATATTAGAGGGAGTCCAACAAGTTTGTGATGATTCACGTAAGGAAATCGAAATGTAAGATTATTCGTCAATGGAGGTATAAGACAACACACCAAGTAATTATACGCGACGAGTTTTCATGTTGACGATCCC [...]
+
@@ -667,10 +668,10 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGGAGTACGGGGCTTGTCCGCGAGTGTCAACCGGGTTTTACAAAGGAGAACTTCCAACATCAGTGTATGGGATGTTTCAAACACCCCCAGAGACGGAGACAATAGTGTGGTCACGTACATTTAGGAAGATAAAAATAACAACAACAGAAGGTGTGAGGCGCAAGGTACATGCTCTTACCCCACTCTCAGCACGTAGGGAGCGGAGTGTGGGAAGACCAACAAGCCCGTCGCCTCTACCAAATACAGTGTTTAGGTGTGTCGGAGGGCAGAAACCAACGAAAGAAAGGAAACGATCAACACTTATATAGTGTCCTGTCGGGCCCAAATCCTAAGAGACCTTAGGTTTACCACATTAGTACTAAACAGCCTGTTGTATACCGTGAGCCCCCCACTTCGATCTGTAAAATGGTAATCCCTTGTAAAACCTCATCTCCAAAAACAGTATACGCAGGTACAGCTGATGTGATCCTCT [...]
+
KZA<P=@CqUIXXKtXSYV0WE?B/3$?XqKIX4H:kOV9H?cV^kR~Gy?~~<\~~yWN~vT~zPMsS*kJ~M~o|smads^]xlH~~s at b5~yj<~qh[D~~~~abHbzjJ`lOrmV~VYOCVC:SV[p_N\fGd5~yzU~PbKgm2~~~j]g~nUsnl~o|fV~D~XKYc{B~lbk?j:`C(9sGa*mnP~z=~}qyX^V^Zx_Szoblv1{ccN_LuschfG%ngazM{[~Aw:Jnb1ttOZ[PV|RWk^J~D~rm`QqbZ`2vzxEeCSL=ZYU~o3~zladL~uZzj~XdNuue7nfS~0ne[M^YUOtns)Kp\SmZugk^r]~pLm`?~~E~~N~~s\~Zf~gyQz]~b~|V~D~|yI~zox@~yblxn\P~~nzPIzmh^~di|sxW~`[`vc$s~~qkq?EI)LzrYrfo%v^0<;~Ve~qC~sLkdX9~tnZ~VTU_UQ0~9~~~~n|gpZT`ngotO~r{ozQl\f|sfqd3p]~mi\ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2772/ccs/fwd np:i:6 rq:f:0.993765
- AGCAGTGGTATCAACGCAGAGTACGGGGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCCTGGATGCAATTGTGCTCGCCATTTCAACTTAGTGCAGTTGCTAAAGTGCCAACTAAGGTTCGTCTTGAAGC [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2772/ccs/fwd np:i:6 rq:f:0.994156
+ AGCAGTGGTATCAACGCAGAGTACGGGGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCCTGGATGCAATTGTGCTCGCCATTTCAACTTAGTGCAGTTGCTAAAGTGCCAACTAAGGTTCGTCTTGAAGC [...]
+
- .JYcL?>gfedL0rW_S2C_]d7K4||yX]Mf4r]_Q@]aUSdEz?69p83\ELcf at e:TJ7yaFadeHR\Cw}OX`5rbS+aVRXN^6YHViXPL~|\YI?[C.DID8<N^V2^aZS\F{Ph^C_i>kWQ[`-ixj`ZG~S~j`0~KA|~aib\cXi_;_[ah[hafE`F~O,WJZ;nra>bb].]YXy[MVaK~gZ~JX+s`rBEZXfQhgZaVIB;R~f2@`z_QW\XWxB_<JN<\'89Q]BcBeTEd1M[0LnhN>jX|cVJ?SH0x|fC^R8,AfGdQ)^=BQ+Z_BHCQNnY7jU`f9N_i[BxaK~aS_UI0|}YhIDQ<HYIhYQ`J~QV4OEd`jh`:~ha[Y~ajR~j`@~s]NVUIrtM,GYhQ`eF_.o7YhahQeX^KK&WES<nOdjhjR~[ifE~`gEP|2gsiR~b_]WVfY|Jh_5`E\E^JGdXOG}Y-ea[f5V9OU~`TLHInJh_HfF}Zf5zQ~Z~E^NZXy83aWY [...]
+ .JYcL?>gfedL0rW_S2C_]d7K4||yX]Mf4r]_Q@]aUSdEz?69p83\ELcf at e:TJ7yaFadeHR\Cw}OX`5rbS+aVRXN^6YHViXPL~|\YI?[C.DID8<N^V2^aZS\F{Ph^C_i>kWQ[`-ixj`ZG~S~j`0~KA|~aib\cXi_;_[ah[hafE`F~O,WJZ;nra>bb].]YXy[MVaK~gZ~JX+s`rBEZXfQhgZaVIB;R~f2@`z_QW\XWxB_<JN<\'89Q]BcBeTEd1M[0LnhN>jX|cVJ?SH0x|fC^R8,AfGdQ)^=BQ+Z_BHCQNnY7jU`f9N_i[BxaK~aS_UI0|}YhIDQ<HYIhYQ`J~QV4OEd`jh`:~ha[Y~ajR~j`@~s]NVUIrtM,GYhQ`eF_.o7YhahQeX^KK&WES<nOdjhjR~[ifE~`gEP|2gsiR~b_]WVfY|Jh_5`E\E^JGdXOG}Y-ea[f5V9OU~`TLHInJh_HfF}Zf5zQ~Z~E^NZXy83aWY [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2772/ccs/rev np:i:5 rq:f:0.992486
AAGCAGTTGGTATCAACGCAGAGTACGGGGCGATGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGCTCGCCACAGCGGTGGCATATGTCCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGTGTGTTATAGTTTACGCTAGTCCAATCTGTATCGTGGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAATTGTGCTCGCCATTTCAACTAGTGCAGTTGCTAAAGTGCCAACTAAGGTTCGTCTTGAA [...]
+
@@ -723,18 +724,18 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATTGAACATGGATGCGAACGACATTTCGAAATATACGCAATGAATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTGAGACAATG [...]
+
BhRXXM:<`J^]EQw[RH^R]>^_L/^WEIU6\OCK>*c\EHBW'ENHEGO/]M-U=,PKMaC[IAY=J91LPc[S^[_;ttYN=]h]Z_GHS[E_DA&Y_G]9q>tFvw`\)YNA;c[ZNQ;q_Pt'B@[ZN?]=UW]O at D\G^[_KR;dD7MG<Grp\SIV[RC`AKZS[S[O7_YHF2$$DnpW^A4]IOFGZRMR_8wp[\3luqHB\^?eGww\?>Y5wwVEBs+I[^/ZX`\F:qs[TGQtRER]E[=FWSY]@Md^_;w^E`BtXKFvPt=LO;M2]X>\Y5P`[RuS^Ewk>nS^G^Qv`\.^YSN\JqUNG\FEy`QvRK9uuD at uWX^?BfE=S\5;m,JSM>L*X^8.5Y(ta]@\Oj[^OLu^Q6[RGZS_[PG_R_<tW\S_[^Ta[^`RIV]X1F(Yp\9mY>NnT`[^`Sa^P[CvCoM`[`]E=uq_[[]0pP?tR^[PGJbBKt`ZAcDPDY[]RBuZRAs\=6PZMGZQv`S [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2903/ccs/fwd np:i:6 rq:f:0.993546
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTGGTTCGTACAGCGGTAAATGACTTGTTGAGTCTTGACGTCGACGACCAAAGCGACCACTTTGACCCAATTGCGAACTACTAAATCCTAAGCAAAGACTATTAGGTAGTAGCCAACTTCGTTAATTCCGTTCAGTACTTTTAAAATTCTAAACCGACCATCTTTCCGAGTTGCTTCAAACCCTCGTCCTAATGATTTTACATCGAATAGAACGTCGTAACAAACGCACTACTACATGGAATAGATTCTCTTGTCAAATCGTTTTGTTTTGGCTTTACCCTTGGTAACAAACTTCGACTACGTTCGTACAATTCAGAATAACCTCTACCTCGTTAATTTGAGTTAGTTCGTTAAGGGCTTAAGTAGTTTATTTCTATGATAAGCACTAAATTGACCCTTAATTTCCTCGACTTATTGTTACATCTCGATTTCCCT [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2903/ccs/fwd np:i:6 rq:f:0.993549
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTGGTTCGTACAGCGGTAAATGACTTGTTGAGTCTTGACGTCGACGACCAAAGCGACCACTTTGACCCAATTGCGAACTACTAAATCCTAAGCAAAGACTATTAGGTAGTAGCCAACTTCGTTAATTCCGTTCAGTACTTTTAAAATTCTAAACCGACCATCTTTCCGAGTTGCTTCAAACCCTCGTCCTAATGATTTTACATCGAATAGAACGTCGTAACAAACGCACTACTACATGGAATAGATTCTCTTGTCAAATCGTTTTGTTTTGGCTTTACCCTTGGTAACAAACTTCGACTACGTTCGTACAATTCAGAATAACCTCTACCTCGTTAATTTGAGTTAGTTCGTTAAGGGCTTAAGTAGTTTATTTCTATGATAAGCACTAAATTGACCCTTAATTTCCTCGACTTATTGTTACATCTCGATTTCCCT [...]
+
- a~lTShT2xea`TU`RQ at ejRWnRU$|}}}}}}}}}}}}}}}}}}}}}{qjkmSL>nVy:zRjogSUiUZ~oN~~ng_I]tfL{iSkiVK}khSSlDT`Sif>IMp~kUkd+^>AQz~kg2~rStNxSUi3xTnSUp=ccjG~oG|kUMq{RPBMXYtNY~qhll?iEiDnS7{Rg\{UvYpE~OBb=WUU>G/WHF&d`IG['^)D1,O;J$U6>>FZ\0h)MSYa]0IWQ>sN,MenTjT1uPPXJQ\&p{dbS9iP>Dznfj7zVioViR&CR?]`@kSM?lhVoe at MiV}5yS>PWOyUlV]xTnV>||WUk:~~}kM~~zF{U@}xa,kg_~IonBcB>v{TO{UfPTob*cYwQ>Z=SVg^|VhkE~iQVF}oVk*)poQeM{U`.}lc;hM}gl\fTT[zD_>WwS6qUlkgf[6LVQ>{}TTOjiF>F]RReVn=||McSQ/mg\yTw6||D~kSkhV\}T\~fEaLC_PSQ?ihP~n;~t[ [...]
+ a~lTShT2xea`TU`RQ at ejRWnRU$|}}}}}}}}}}}}}}}}}}}}}{qjkmSL>nVy:zRjogSUiUZ~oN~~ng_I]tfL{iSkiVK}khSSlDT`Sif>IMp~kUkd+^>AQz~kg2~rStNxSUi3xTnSUp=ccjG~oG|kUMq{RPBMXYtNY~qhll?iEiDnS7{Rg\{UvYpE~OBb=WUU>G/WHF&d`IG['^)D1,O;J$U6>>FZ\0h)MSYa]0IWQ>sN,MenTjT1uPPXJQ\&p{dbS9iP>Dznfj7zVioViR&CR?]`@kSM?lhVoe at MiV}5yS>PWOyUlV]xTnV>||WUk:~~}kM~~zF{U@}xa,kg_~IonBcB>v{TO{UfPTob*cYwQ>Z=SVg^|VhkE~iQVF}oVk*)poQeM{U`.}lc;hM}gl\fTT[zD_>WwS6qUlkgf[6LVQ>{}TTOjiF>F]RReVn=||McSQ/mg\yTw6||D~kSkhV\}T\~fEaLC_PSQ?ihP~n;~t[ [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2903/ccs/rev np:i:6 rq:f:0.991972
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTACTGGTTCGTACAGCGGTAAATGACTTGTTGAGTCTTGACGTCGACGACCAAAGCGACCACTTTGACCCAATTGCGAACTACTAAATCCTAAGCAAAGGACTATTAGGTAGTAGCCAACTTCGTTAATTCCGTTCAGTACTTTTAAATTCTAACCGACCATCTTTTCCGAGTTGCTTCAAACCCTCGTCCTAATGATTTACATCGAATAGAACGTCGTACAAACGCACTACTACATGGAATAGATTCTCTTGTCAAATCGTTTTGTTTTGGCTTTACCCTTGGTAACAAACTTCGACTACGTTCGTACAATTCAGAATAACCTCTACCTCGTTAATTTGAGTTAGTTCGTTAAGGGCTTAAGTAGTTATTTTCTATGATAAGCACTAAATTGACCTTAATTTCCTCGACTTATTGTTACATCTCGATTTCCCTT [...]
+
1[UloCP1PcU:Q\yQTkmVVTSjj%||{whSKOXZY_b`XPKMVdqrja[UOQiqneI>cU}lDRTjoUP?haCu^gVo`9GCOvQOShl/_VojTTiAWjWnIpG~qAjSgIlnkB~{RTI`v\tR`Oh+YZjNPi`Agg`XpgM}Uj8sp'V^Y\TF_nD~dkWhkRZ~`~R8sgQ+]L]7zV~QClOPOQmk:uV_BtvE^PdHo0`WoZ~k^k$wlRD^BOUQrVlW~SC~pK{macA_W~_[MQUWNSg`RcEPNTd5BNVpaOI`N^bJIp_D7Q(H at O_VD__J?xTm]cMXJsa\INlM4^:r]I`M7bojM at kraBu`0n_RIim9]0g^Ur`1YeN+7N(IKIc`;+R]N[^`VpLsadNQd_TpRq^_XEB\5OL.kUpFrnNdNMq^NLraNM[Rf7jcI9iUnO]`D8.J-`Sc^HaHHE[MdN]Xa\;3d'9;KPn)h=Q7noMn3TLLZKhaLqGHi`^DZa^aO`DYkHqqK^ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2944/ccs/fwd np:i:8 rq:f:0.995773
- AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATAATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCCACCTCAACGCTATGAACGTTAGTTGAGACA [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2944/ccs/fwd np:i:8 rq:f:0.995775
+ AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGTAAAACTTGTCACCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATAATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCTAGACAGTCATGTCTCTTCCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCCACCTCAACGCTATGAACGTTAGTTGAGACA [...]
+
- dpZCn[[Z~qH[@.tOWBaj_mZZLAm~~d~K~viX_E~~^p2~ZCb]QkrJ~tN~svn`}R\_Z~an1Pa@|Tj%I4Td~VmEgguswm at mDQg\jL[bt,vTNn7m~[W*ZYQ~aTtYT_{`FvV~mvpXO{L~ttlPYG_sUS\Z$s\eiijm9~~vNj=EMWcenj`B_gKFwwleXubAuumhWDpuPfSXjRfdgGU`=f.[f5,gjR+|@kumRqlIwvuOWuPWLV'qs~i at nY/Lg;A9LbBNheiJEJjP4_hjGpDWjQuW[DeG^AVCfSMuPadLjdYLKtfg8ugKmMjijJugVTe;SUk;WlfYXI=8hKvdlGwvMHqNdic,rjfW(hg<^QjNeYveNf at ltM0qrk@s6WKZS9~^PWDF3JaiNeeTM='bdcjNkeSJQUd`KeI0>/e\fj6uvdYvgmK1ifmk`=Qu,VShNmgL*tvsVNWZu^QqekQgi%~ZX6VUBGj:aLjEDe+QKeLmje^wcfYU8U [...]
+ dpZCn[[Z~qH[@.tOWBaj_mZZLAm~~d~K~viX_E~~^p2~ZCb]QkrJ~tN~svn`}R\_Z~an1Pa@|Tj%I4Td~VmEgguswm at mDQg\jL[bt,vTNn7m~[W*ZYQ~aTtYT_{`FvV~mvpXO{L~ttlPYG_sUS\Z$s\eiijm9~~vNj=EMWcenj`B_gKFwwleXubAuumhWDpuPfSXjRfdgGU`=f.[f5,gjR+|@kumRqlIwvuOWuPWLV'qs~i at nY/Lg;A9LbBNheiJEJjP4_hjGpDWjQuW[DeG^AVCfSMuPadLjdYLKtfg8ugKmMjijJugVTe;SUk;WlfYXI=8hKvdlGwvMHqNdic,rjfW(hg<^QjNeYveNf at ltM0qrk@s6WKZS9~^PWDF3JaiNeeTM='bdcjNkeSJQUd`KeI0>/e\fj6uvdYvgmK1ifmk`=Qu,VShNmgL*tvsVNWZu^QqekQgi%~ZX6VUBGj:aLjEDe+QKeLmje^wcfYU8U [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/2944/ccs/rev np:i:8 rq:f:0.996531
AAGCAGTGGTATCAACGCAGAGTACGGGGTTGGTGTATTTATCCGCTACGTGGGTGGATGAACATGGATGCGAACGACATTTCGAAATATACGCAATGATATCCAACCCTACCGAAACAGCAATAATTGTAGAAGGTAGCATATCATGCCGAGAGTTTACTACGTTGTAGCGAGTTTAGTTGAAATAGTTTGTGATGTGTAAACTAAAACATACCAAATGGGTAAACTTGTCACCCCCATTTACATTGCGACAGACACAGTTATGGAGTGGATGGAAGTGTGTTCGACTGTCAAGACCCTTCTATAATAGTCGAACCAGTACGGTAAGTGGGCAACATGCCCATATAAGTCGAAGCATTTCAAATGGTTCATCCAGTAGACGACGATGTCCTAGACAGTCATGTCTCTTCCCATTTGAAGTCATGTAGTGGTTGTCTACTTTTTCATTGAAGACGTCCACCTCAACGCTATGAACGTTAGTTGAGACAAT [...]
+
@@ -787,18 +788,18 @@ Test ccs on 100 zmws from the lexogen-SIRV dataset, using --byStrand
AAGCAGTGGTATCAACGCAGAGTACGGGGGGCGACAATTGTGGACCGTATGGACTCCATTATGCTGGACTCCTCGGGTCAACCGCTCTAAAGCGAAGTTGTTGGACAAACAGTTATGCGTAACTGTAAAGCAAGGTGCCCAAAGTAGACTGAGCGACAGTCGAAACCAGCCCCAATGAACAAGACGCCATTGCAAAACGTCTATACGCTACGGTCAAAGACGCTTCCACACCACATGCTCTCATGTAGCCTACCTTACGAAGAAATCGCACAAGTCGGTCGCCCAGCGGTGGCATATGTCTTGCCTAACGTTTCTAGACCGATCAGCCTCACGAGTAGCCTGCTTGTGGTGTTTATAGTTTACGCTAGTCCAATCTGTATCGTGCCGCTTGGTATGGCTATTGTCGGCCTGGATGCAAGCACTAACGTGGTCATCAGACTGGTCTGCGCTATAATCTACGCAATAGAGGCACCAGCGGTCGTTTGAAGCC [...]
+
C~]h]`0 at wkVZdS~e_Wuduer]i4~wowp`_\gGy:~S\GytX~foqGDw\eqG~l1{OEVip3~rho6~rfE^I\hR~Y~dRYRY?~|ehP`~_Vxe_~Pxoh7~~_ccO~q.Zgb\d~hW2kJ~~Lge~Q~VKN~~@~hNF^boeoHV\<Isiteaed=~vU~[b6~~`UWS]Q~gBr_UN`CvbJ~Jd9~~|hN^c at R=dhdhsuhQupQK~~dte_i^~Vztg\Y~uit\baAfrivpOmULW~]sV~LwnRcJnNI~~rieeXba~bZSDgXbdGyb\WcDnaG~aflnYcnRV~PM|[S~ie>~{gEn9lU~fVriueW~\gefeucFpM6j\ch:eJC&=ANKpvSVk^F~~\eMbfl`WY~c~qjoOn\ph_SfY~eiV~PsGq`3yNmVO~drh?mF~[U~rGbhQ~eh\dkP~hcF?~TcmriZJjaDQ~qhZSSTiilZNnUcoWfdRP~VretD~dmM~sLdQqrgK,~kdb~KMn [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3119/ccs/fwd np:i:6 rq:f:0.99553
- AAGCAGTGGTATCAACGCAGAGTACGGGGCATACTGCAAGACTTGTAGGCCCATGAATTACCCGCTTAGGCAATGGGTAGACCTTTCCTTGCCGCGTGGAACAAACCGCCATGAGTGTTTTACGTTTACGGTCGGCGACCGGAGTCACAGCGCGACCAACGGGGCCAGGCAAAGGCCCATAGGCCTTTTCCATCGGCACGCGACCGATTCCATCAAGTGTTAGGTGCAATCCCATTCGGGGACGGACACGCGAGAGCGTTAGTCGGCGCGTGCGCGGACTATTTAGCGAAGGTCGCCGATCGTTTGCCCGTAAAACTAACTGGCAAAAGCCTAAGTGCTGTTTCGGGTGCAATGGTATAACTTCCCACATTTAGCCGAATAGCGCCAACAGCGTTATTATTTGGAACCAAGCAGTGGGCGATGTCAGCGACAATTCCACTTTGGTAGAGGTCGTTCTTTTGTAGAAAACAATCTAACATAACTATGACAC [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3119/ccs/fwd np:i:6 rq:f:0.995712
+ AAGCAGTGGTATCAACGCAGAGTACGGGGCATACTGCAAGACTTGTAGGCCCATGAATTACCCGCTTAGGCAATGGGTAGACCTTTCCTTGCCGCGTGGAACAAACCGCCATGAGTGTTTTACGTTTACGGTCGGCGACCGGAGTCACAGCGCGACCAACGGGGCCAGGCAAAGGCCCATAGGCCTTTTCCATCGGCACGCGACCGATTCCATCAAGTGTTAGGTGCAATCCCATTCGGGGACGGACACGCGAGAGCGTTAGTCGGCGCGTGCGCGGACTATTTAGCGAAGGTCGCCGATCGTTTGCCCGTAAAACTAACTGGCAAAAGCCTAAGTGCTGTTTCGGGTGCAATGGTATAACTTCCCACATTTAGCCGAATAGCGCCAACAGCGTTATTATTTGGAACCAAGCAGTGGGCGATGTCAGCGACAATTCCACTTTGGTAGAGGTCGTTCTTTTGTAGAAAACAATCTAACATAACTATGACAC [...]
+
- [~FD^E_ at zfMOX4yE[F_YP]d6VA~~~ZNMd\d. at 5k]ODE}]he7w2nx]h]F~V~dD~{Z\Z~gO~\X~f6~y\L^bK|>x`Mx*JN/XW\]c8'>NZ3p_Ls^KS7e[%X`Y=y~~f\]>~~f\Q~h]O~\]I(]El,\d/cZP]\\F[MKgAr;=icP3kCMrNCbcNq.[`SVFMh'F;bafEfOWMFLLQPXNA at 3o\RY~A~edFW~^hX0yOOyPEGB`b%=RMIp[$p[Y]FEB%ETK]YGd]NF[\A~P]h[BfIOI>c5W4B)]LZcN8SScEK<EbOuOZ[*eGeh\]9[eC7at^g<~~fEeFfDfCaEAr~{^JfeCdUE\ULEGz|[6~a3D[X~hO~U>UHeZFj6eVJW^Fyzg];|[/_Ld[X]=tGuZJX\^X~:Go:JmaP~NlKw4_HWOYc7}}VZbZc`R;dVgF`E}_~N~WMJ{b/~bBajT~neQ^qO%~~~PjKOB~~Y:Lql`nU~fpYN~eoDndm`[] [...]
+ [~FD^E_ at zfMOX4yE[F_YP]d6VA~~~ZNMd\d. at 5k]ODE}]he7w2nx]h]F~V~dD~{Z\Z~gO~\X~f6~y\L^bK|>x`Mx*JN/XW\]c8'>NZ3p_Ls^KS7e[%X`Y=y~~f\]>~~f\Q~h]O~\]I(]El,\d/cZP]\\F[MKgAr;=icP3kCMrNCbcNq.[`SVFMh'F;bafEfOWMFLLQPXNA at 3o\RY~A~edFW~^hX0yOOyPEGB`b%=RMIp[$p[Y]FEB%ETK]YGd]NF[\A~P]h[BfIOI>c5W4B)]LZcN8SScEK<EbOuOZ[*eGeh\]9[eC7at^g<~~fEeFfDfCaEAr~{^JfeCdUE\ULEGz|[6~a3D[X~hO~U>UHeZFj6eVJW^Fyzg];|[/_Ld[X]=tGuZJX\^X~:Go:JmaP~NlKw4_HWOYc7}}VZbZc`R;dVgF`E}_~N~WMJ{b/~bBajT~neQ^qO%~~~PjKOB~~Y:Lql`nU~fpYN~eoDndm`[] [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3119/ccs/rev np:i:6 rq:f:0.992635
AAGCAGTGGTATCAACGCAGAGTACGGGGCAATACTGCAAGACTTGTAGGCCCATGAATTACCCGCTTAGGCAATGGGTAGACCTTTCCTTGCCGCGTGGAACAAACCGCCATGAGTGTTTTACGTTTACGGTCGGCGACCGGAGTCACAGCGCGACCAACGGGGCCAGGCAAAGGCCCATAGGCTTTTCCATCGGCACGCGACCGATTCCATCAAGTGTTAGGTGCAATCCCCATTCGGGACGGACACGCGAAGAGCGTTAGTCGGCGCGTGCGCGGGACTATTTAGCGAAGGTCGCCGATCGTTTGCCCGTAAAAACTAACTGGCAAAAGCCTAAGTTGCTGTTTCGGGTGCAATGGTATAACTTCCCACATTTAGCCGGAATAGCGCCAACAGCGTTATTATTTGGAACCAAGCAGTGGGCGATGTCAGCGACAATTCCACTTTGGTAGAGGTCGTTCTTTTGTAGAAAACAATCTAACATAACTAT [...]
+
%a+DcWa<]=df]I~]XYTENJegP(cy|]&OPJZPYGW~\h_JgHegFr<YcXf\Un>h03v{DX,t[Lz]VadCyeQb-4Nl9v^MdAtUO{[QIQKfZ~\;liDbTN~gPZa<[ZGt~~h^\J~qZBM~g^M~^\b;Q8wIXbYh^hYGX\BeL|?X]<~~~P~eJdZ9Yo:z6~z^ehM~^<zbX=_'JN;Z\hZVTYR8UCcRYKaceGW|[>,>LV=id[\C^b?uatfFh]D~maHMnO\fSVXG9,DQCO[UcgKf]L}]JHDdF\XY5}~g^bd=UV_W^[UyM~gZG=kW5K\F7Vm[>~mVf,]btaZgF|(N7yB,t^pC:gNTvI$SYZg[4}p\,]LMV.Vxb,=2=`RaARzD~hJVA7YZfW:x.ZVf&aC/TI\MiZX[^ZM`=8\T2{H*ySwJv3yVVMOd8~~ZRJCCI/bF[EeIDkMlO}f\;bbJ}Lf\hMe;\[A}U/MAQHMMY3ziZ]Ipf^gX}EegV~]OeJ [...]
- @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3147/ccs/fwd np:i:7 rq:f:0.995375
- AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCCTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCCTAGTCCCGGACTCACCGAACCTACACCGTTCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTGTGGGCTAGGGCACCGCGTTTTGAAGTAATAGATGTAACCTACCACCCATAAACTGCTCTAAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGAGAATTTACGGTGGTAATTTCGCACACTTCGCACGTTTA [...]
+ @m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3147/ccs/fwd np:i:7 rq:f:0.99463
+ AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCCTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCCTAGTCCCGGACTCACCGAACCTACACCGTTCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCGGTCTACTATCCATCGTTCATGTTCGGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTGTGGGCTAGGGCACCGCGTTTTGAAGTAATAGATGTAACCTACACCCATAAACTGCTCTAAACAATTTAAGTTCGTCGTCGGCCTTCTTTTTATATCACTAACGTGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGAGAATTTACGGTGGTAATTTCGCACACTTCGCACGTTTA [...]
+
- Ar:GV<i>pQ]f9Kh7FJZY^]kIG%hllllllllllkfabgllllllllllk60r`Zb[Hm^G\^Kh^MY_L^>rKKjV^M]UJj=y\ZJWRNp[GK%nmn_Wf&^RKhBCXDF;\WPm.^U at 2R6_HNh.yJWF5X`\e]YeHCl]KHe^]j\[PJ0mfVUYK\[jHgT;MO/m7Zc9T\<Z6h?{^lK][PHYSZ]cG*;6IcOSG8OS\9kX1ZZbIB^<PZ>cPe]I5kkYJNmb]E'WU at mmKo]2kkK^<xWKW:oom\LmYg,LIWY\X[kEc>xkH7G\7^hV`4n[Jo\HdFV4V7.CABmlMo]Y`J\lK\lFw;r_lJ6iln]Jj\VKNLd?kIGi]k_6b][=r^j^J`EJXKlJ0S7dhYeYKWfQP45WTGAe[HMHDkk\j7 at co\Z.aZMmKiB_5Y96>hbLlJkFF95VZWX]FYk7[RFKINPgJ^ZR^MoB2NSEmlZHKml;ukAlHnnG[7[D at 97E8X5H9]Arqb [...]
+ Ar:GV<i>pQ]f9Kh7FJZY^]kIG%hllllllllllkfabgllllllllllk60r`Zb[Hm^G\^Kh^MY_L^>rKKjV^M]UJj=y\ZJWRNp[GK%nmn_Wf&^RKhBCXDF;\WPm.^U at 2R6_HNh.yJWF5X`\e]YeHCl]KHe^]j\[PJ0mfVUYK\[jHgT;MO/m7Zc9T\<Z6h?{^lK][PHYSZ]cG*;6IcOSG8OS\9kX1ZZbIB^<PZ>cPe]I5kkYJNmb]E'WU at mmKo]2kkK^<xWKW:oom\LmYg,LIWY\X[kEb>wjD$Y6I_V\4n[Jo\HdFV4V7.CABmlMo]Y`J\lK\lJ&><|_lJ6iln]Jj\VKNLd?kIGi]k_6b][=r^j^J`EJXKlJ0S7dhYeYKWfQP45WTGAe[HMHDkk\j7 at co\Z.aZMmKiB_5Y96>hbLlJkFF95VZWX]FYk7[RFKINPgJ^ZR^MoB2NSEmlZHKml;ukAlHnnG[7[D at 97E8X5H9]Arqb [...]
@m150825_055401_42161_c100844482550000001823159012311525_s1_p0/3147/ccs/rev np:i:6 rq:f:0.993731
AAGCAGTGGTATCAACGCAGAGTACTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTCCTATACTACGAGGACGTCACCACTGAGGTCTCCGACATGGACACCTAGTCCCGGACTCACCGAACCTACACCGTTCCCTTCAGTGTGTTCTTTCGGAGTAGTGAAAAAACGTTGGTCTTCCCGGTCTACTATCCATCGTTCATGTTCGCTTTTACAAGTTACCTTCAACAATTTTACAAAGCAATGCTTGTGGGCTAGGCACCGCGTTTTGAAGTAAATAGATGTAACCTACCACCCATAAACTGCTCTAACAATTTAAGTTCGTCGTCGCCTTCTTTTTATATCACTAACGATGTACCTACCTTAGAGCGTTACCAAAGTACATATACAGATTTCTCAATGTATTTGACCTGGCTCTCTGCAATCTCTCTCAAGATGCGTAAGCACTTTCAGTAGGACGAATTTACGGTGGTAATTTCGCACACTTCGCACGT [...]
+
diff --git a/tests/cram/tiny.t b/tests/cram/tiny.t
index a997a8d..7464a84 100644
--- a/tests/cram/tiny.t
+++ b/tests/cram/tiny.t
@@ -9,7 +9,7 @@ Test a tiny collection of a few ZMWs, write to FASTQ for inspection
@m150404_101626_42267_c100807920800000001823174110291514_s1_p0/109700/ccs np:i:18 rq:f:0.999452
GCGTGCTTGTGGTGGGTAACCGTCGTATTCCCGGCGCGTTTATTCAGCAACTGAAAAATGGCCGGTGGCATGTCATGCAGCGTGTGGCTGGGAAAAACCGTTACCCCATTGATGTGGTGAAAATCCCGATGGCGGTGCCGCTGACCACGGCGTTTAAACAAAATATTGAGCGGATACGGCGTGAACGTCTTCCGAAAGAGCTGGGCTATGCGCTGCAGCATCAACTGAGGATGGTAATAAAGCGATGAAACATACTGAACTCCGTGCAGCCGTACTGGATGCACTGGAGAAGCATGACACCGGGGCGACGTTTTTTGATGGTCGCCCCGCTGTTTTTGATGAGGCGGATTTTCCGGCAGTTGCCGTTTATCTCACCGGCGCTGAATACACGGGCGAAGAGCTGGACAGCGATACCTGGCAGGCGGAGCTGCATATCGAAGTTTTCCTGCCTGCTCAGGTGCCGGATTCAGAGCTGGATGCGTGGATGGAG [...]
+
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~{~~~~:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2~~~~~~~~~~m~~~~~~~~~~~~~~~d~~~~m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Y~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~u~~~~~~~~%~~~~~~~~~~~~~a~~~~~~~3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [...]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~{~~~~:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2~~~~~~~~~~m~~~~~~~~~~~~~~~d~~~~l~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Y~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~u~~~~~~~~%~~~~~~~~~~~~~a~~~~~~~3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [...]
@m150404_101626_42267_c100807920800000001823174110291514_s1_p0/110513/ccs np:i:25 rq:f:0.999989
AAAACTGTACGATAAACGGTACGCTGAGGGCGGAAAAAATCGTCGGGGACATTGTAAAGGCGGCGAGCGCGGCTTTTCCGCGCCAGCGTGAAAGCAGTGTGGACTGGCCGTCAGGTACCCGTACTGTCACCGTGACCGATGACCATCCTTTTGATCGCCAGATAGTGGTGCTTCCGCTGACGTTTCGCGGAAGTAAGCGTACTGTCAGCGGCAGGACAACGTATTCGATGTGTTATCTGAAAGTACTGATGAACGGTGCGGTGATTTATGATGGCGCGGCGAACGAGGCGGTACAGGTGTTCTCCCGTATTGTTGACATGCCAGCGGGTCGGGGAAACGTGATCCTGACGTTCACGCTTACGTCCACACGGCATTCGGCAGATATTCCGCCGTATACGTTTGCCAGCGATGTGCAGGTTATGGTGATTAAGAAACAGGCGCTGGGCATCAGCGTGGTCTGAGTGTGTTACAGAGGTTCGTCCGGGAACGG [...]
+
diff --git a/tests/python/test_tool_contract.py b/tests/python/test_tool_contract.py
index de47ca1..30a41cd 100755
--- a/tests/python/test_tool_contract.py
+++ b/tests/python/test_tool_contract.py
@@ -22,7 +22,7 @@ CHUNK_INDEX = 1
class TestCCSApp(pbcommand.testkit.PbTestApp):
# FIXME eventually the 'ccs' binary should handle TCI directly
- DRIVER_BASE = op.join(CCS_DIR, "scripts", "task_pbccs_ccs")
+ DRIVER_BASE = os.environ['__PBTEST_CCS_EXE']
REQUIRES_PBCORE = True
INPUT_FILES = [tempfile.NamedTemporaryFile(suffix=".subreadset.xml").name]
TASK_OPTIONS = {
diff --git a/tests/unit/TestConsensus.cpp b/tests/unit/TestConsensus.cpp
index 17a8ca8..f2ea29b 100644
--- a/tests/unit/TestConsensus.cpp
+++ b/tests/unit/TestConsensus.cpp
@@ -41,12 +41,13 @@
#include <pbbam/Accuracy.h>
#include <pbbam/LocalContextFlags.h>
+#include <pbcopper/cli/CLI.h>
+
#include <pacbio/ccs/Consensus.h>
+#include <pacbio/ccs/ConsensusSettings.h>
#include <pacbio/data/ReadId.h>
#include <pacbio/data/SubreadResultCounter.h>
-#include <OptionParser.h>
-
using namespace PacBio::CCS;
typedef ReadType<ReadId> Subread;
@@ -63,10 +64,7 @@ TEST(ConsensusTest, TestReadFilter)
std::vector<uint8_t>(seq.size(), 0), flags, .99});
}
- auto parser = optparse::OptionParser();
- ConsensusSettings::AddOptions(&parser);
- const auto options = parser.parse_args({});
- ConsensusSettings settings(options);
+ ConsensusSettings settings(PacBio::CLI::Results(ConsensusSettings::CreateCLI("", "")));
settings.MinLength = 10;
settings.MinReadScore = 0.0;
diff --git a/tests/unit/TestIntegrator.cpp b/tests/unit/TestIntegrator.cpp
index 6ac09b7..09f6ea4 100644
--- a/tests/unit/TestIntegrator.cpp
+++ b/tests/unit/TestIntegrator.cpp
@@ -111,7 +111,7 @@ const IntegratorConfig cfg(std::numeric_limits<double>::quiet_NaN());
Read MkRead(const string& seq, const SNR& snr, const string& mdl, const vector<uint8_t>& pw)
{
- vector<uint8_t> ipd(0, seq.length());
+ vector<uint8_t> ipd(seq.length(), 0);
return Read("NA", seq, ipd, pw, snr, mdl);
}
@@ -120,7 +120,7 @@ TEST(IntegratorTest, TestLongTemplate)
{
// TODO: Write a test for a longer molecule
const string mdl = P6C4;
- vector<uint8_t> pw(longTpl.length(), 1);
+ vector<uint8_t> pw(longRead.length(), 1);
MonoMolecularIntegrator ai(longTpl, cfg, snr, mdl);
EXPECT_EQ(State::VALID,
ai.AddRead(MappedRead(MkRead(longRead, snr, mdl, pw), StrandType::FORWARD, 0,
@@ -130,7 +130,7 @@ TEST(IntegratorTest, TestLongTemplate)
void TestTiming(const string& mdl)
{
- const vector<uint8_t> pws(longTpl.length(), 2);
+ const vector<uint8_t> pws(longRead.length(), 2);
const size_t nsamp = 5000;
MonoMolecularIntegrator ai(longTpl, cfg, snr, mdl);
const auto stime = std::chrono::high_resolution_clock::now();
@@ -331,10 +331,11 @@ TEST(IntegratorTest, TestMultiMutationEquivalenceSP1C1v2) { MultiEquivalence(SP1
TEST(IntegratorTest, TestP6C4NoCovAgainstCSharpModel)
{
const string tpl = "ACGTCGT";
- const vector<uint8_t> pw(tpl.length(), 1);
auto mdl = P6C4;
MultiMolecularIntegrator ai(tpl, cfg);
+ const string readSeq = "ACGTACGT";
+ const vector<uint8_t> pw(readSeq.length(), 1);
EXPECT_EQ(State::VALID,
ai.AddRead(MappedRead(MkRead("ACGTACGT", snr, mdl, pw), StrandType::FORWARD, 0,
tpl.length(), true, true)));
diff --git a/tests/unit/TestLoadModels.cpp b/tests/unit/TestLoadModels.cpp
index 0a57f44..1d73655 100644
--- a/tests/unit/TestLoadModels.cpp
+++ b/tests/unit/TestLoadModels.cpp
@@ -91,12 +91,12 @@ const string longRead =
"CTGCGGCATTTTGTCCGCGCCGGGCTTCGCTCACTGTTCAGGCCGGAGCCACAGACCGCCGTTGAACGGATGCT"
"AATTACTATCTCCCGAAAGAATC";
-const std::vector<uint8_t> longPws(837, 2);
+const std::vector<uint8_t> longPws(longRead.size(), 2);
const IntegratorConfig cfg(-100.0); // disable zscore filtering
Read MkRead(const string& seq, const SNR& snr, const string& mdl, const vector<uint8_t>& pw)
{
- vector<uint8_t> ipd(0, seq.length());
+ vector<uint8_t> ipd(seq.length(), 0);
return Read("NA", seq, ipd, pw, snr, mdl);
}
}
diff --git a/tests/unit/TestPolish.cpp b/tests/unit/TestPolish.cpp
index bd5e441..1c5fd6e 100644
--- a/tests/unit/TestPolish.cpp
+++ b/tests/unit/TestPolish.cpp
@@ -54,7 +54,7 @@ namespace {
Read MkRead(const std::string& seq, const SNR& snr, const std::string& mdl)
{
- std::vector<uint8_t> cov(0, seq.length());
+ std::vector<uint8_t> cov(seq.length(), 0);
return Read("NA", seq, cov, cov, snr, mdl);
}
diff --git a/third-party/cpp-optparse/OptionParser.cpp b/third-party/cpp-optparse/OptionParser.cpp
index 359b7a9..2b9077f 100644
--- a/third-party/cpp-optparse/OptionParser.cpp
+++ b/third-party/cpp-optparse/OptionParser.cpp
@@ -7,16 +7,16 @@
#include "OptionParser.h"
-#include <cstdlib>
#include <algorithm>
-#include <complex>
#include <ciso646>
+#include <complex>
+#include <cstdlib>
#if defined(ENABLE_NLS) && ENABLE_NLS
-# include <libintl.h>
-# define _(s) gettext(s)
+#include <libintl.h>
+#define _(s) gettext(s)
#else
-# define _(s) ((const char *) (s))
+#define _(s) ((const char*)(s))
#endif
using namespace std;
@@ -24,554 +24,541 @@ using namespace std;
namespace optparse {
////////// auxiliary (string) functions { //////////
-class str_wrap {
+class str_wrap
+{
public:
- str_wrap(const string& l, const string& r) : lwrap(l), rwrap(r) {}
- str_wrap(const string& w) : lwrap(w), rwrap(w) {}
- string operator() (const string& s) { return lwrap + s + rwrap; }
- const string lwrap, rwrap;
+ str_wrap(const string& l, const string& r) : lwrap(l), rwrap(r) {}
+ str_wrap(const string& w) : lwrap(w), rwrap(w) {}
+ string operator()(const string& s) { return lwrap + s + rwrap; }
+ const string lwrap, rwrap;
};
-template<typename InputIterator, typename UnaryOperator>
-static string str_join_trans(const string& sep, InputIterator begin, InputIterator end, UnaryOperator op) {
- string buf;
- for (InputIterator it = begin; it != end; ++it) {
- if (it != begin)
- buf += sep;
- buf += op(*it);
- }
- return buf;
-}
-template<class InputIterator>
-static string str_join(const string& sep, InputIterator begin, InputIterator end) {
- return str_join_trans(sep, begin, end, str_wrap(""));
-}
-static string& str_replace(string& s, const string& patt, const string& repl) {
- size_t pos = 0, n = patt.length();
- while (true) {
- pos = s.find(patt, pos);
- if (pos == string::npos)
- break;
- s.replace(pos, n, repl);
- pos += repl.size();
- }
- return s;
-}
-static string str_replace(const string& s, const string& patt, const string& repl) {
- string tmp = s;
- str_replace(tmp, patt, repl);
- return tmp;
-}
-static string str_format(const string& s, size_t pre, size_t len, bool indent_first = true) {
- stringstream ss;
- string p;
- if (indent_first)
- p = string(pre, ' ');
-
- size_t pos = 0, linestart = 0;
- size_t line = 0;
- while (true) {
- bool wrap = false;
-
- size_t new_pos = s.find_first_of(" \n\t", pos);
- if (new_pos == string::npos)
- break;
- if (s[new_pos] == '\n') {
- pos = new_pos + 1;
- wrap = true;
+template <typename InputIterator, typename UnaryOperator>
+static string str_join_trans(const string& sep, InputIterator begin, InputIterator end,
+ UnaryOperator op)
+{
+ string buf;
+ for (InputIterator it = begin; it != end; ++it) {
+ if (it != begin) buf += sep;
+ buf += op(*it);
+ }
+ return buf;
+}
+template <class InputIterator>
+static string str_join(const string& sep, InputIterator begin, InputIterator end)
+{
+ return str_join_trans(sep, begin, end, str_wrap(""));
+}
+static string& str_replace(string& s, const string& patt, const string& repl)
+{
+ size_t pos = 0, n = patt.length();
+ while (true) {
+ pos = s.find(patt, pos);
+ if (pos == string::npos) break;
+ s.replace(pos, n, repl);
+ pos += repl.size();
}
- if (line == 1)
- p = string(pre, ' ');
- if (wrap || new_pos + pre > linestart + len) {
- ss << p << s.substr(linestart, pos - linestart - 1) << endl;
- linestart = pos;
- line++;
+ return s;
+}
+static string str_replace(const string& s, const string& patt, const string& repl)
+{
+ string tmp = s;
+ str_replace(tmp, patt, repl);
+ return tmp;
+}
+static string str_format(const string& s, size_t pre, size_t len, bool indent_first = true)
+{
+ stringstream ss;
+ string p;
+ if (indent_first) p = string(pre, ' ');
+
+ size_t pos = 0, linestart = 0;
+ size_t line = 0;
+ while (true) {
+ bool wrap = false;
+
+ size_t new_pos = s.find_first_of(" \n\t", pos);
+ if (new_pos == string::npos) break;
+ if (s[new_pos] == '\n') {
+ pos = new_pos + 1;
+ wrap = true;
+ }
+ if (line == 1) p = string(pre, ' ');
+ if (wrap || new_pos + pre > linestart + len) {
+ ss << p << s.substr(linestart, pos - linestart - 1) << endl;
+ linestart = pos;
+ line++;
+ }
+ pos = new_pos + 1;
}
- pos = new_pos + 1;
- }
- ss << p << s.substr(linestart) << endl;
- return ss.str();
-}
-static string str_inc(const string& s) {
- stringstream ss;
- string v = (s != "") ? s : "0";
- long i;
- istringstream(v) >> i;
- ss << i+1;
- return ss.str();
-}
-static unsigned int cols() {
- unsigned int n = 80;
+ ss << p << s.substr(linestart) << endl;
+ return ss.str();
+}
+static string str_inc(const string& s)
+{
+ stringstream ss;
+ string v = (s != "") ? s : "0";
+ long i;
+ istringstream(v) >> i;
+ ss << i + 1;
+ return ss.str();
+}
+static unsigned int cols()
+{
+ unsigned int n = 80;
#ifndef _WIN32
- const char *s = getenv("COLUMNS");
- if (s)
- istringstream(s) >> n;
+ const char* s = getenv("COLUMNS");
+ if (s) istringstream(s) >> n;
#endif
- return n;
-}
-static string basename(const string& s) {
- string b = s;
- size_t i = b.find_last_not_of('/');
- if (i == string::npos) {
- if (b[0] == '/')
- b.erase(1);
+ return n;
+}
+static string basename(const string& s)
+{
+ string b = s;
+ size_t i = b.find_last_not_of('/');
+ if (i == string::npos) {
+ if (b[0] == '/') b.erase(1);
+ return b;
+ }
+ b.erase(i + 1, b.length() - i - 1);
+ i = b.find_last_of("/");
+ if (i != string::npos) b.erase(0, i + 1);
return b;
- }
- b.erase(i+1, b.length()-i-1);
- i = b.find_last_of("/");
- if (i != string::npos)
- b.erase(0, i+1);
- return b;
}
////////// } auxiliary (string) functions //////////
-
////////// class OptionParser { //////////
-OptionParser::OptionParser() :
- _usage(_("%prog [options]")),
- _add_help_option(true),
- _add_version_option(true),
- _interspersed_args(true) {}
-
-Option& OptionParser::add_option(const string& opt) {
- const string tmp[1] = { opt };
- return add_option(vector<string>(&tmp[0], &tmp[1]));
-}
-Option& OptionParser::add_option(const string& opt1, const string& opt2) {
- const string tmp[2] = { opt1, opt2 };
- return add_option(vector<string>(&tmp[0], &tmp[2]));
-}
-Option& OptionParser::add_option(const string& opt1, const string& opt2, const string& opt3) {
- const string tmp[3] = { opt1, opt2, opt3 };
- return add_option(vector<string>(&tmp[0], &tmp[3]));
-}
-Option& OptionParser::add_option(const vector<string>& v) {
- _opts.resize(_opts.size()+1);
- Option& option = _opts.back();
- string dest_fallback;
- for (vector<string>::const_iterator it = v.begin(); it != v.end(); ++it) {
- if (it->substr(0,2) == "--") {
- const string s = it->substr(2);
- if (option.dest() == "")
- option.dest(str_replace(s, "-", "_"));
- option._long_opts.insert(s);
- _optmap_l[s] = &option;
- } else {
- const string s = it->substr(1,1);
- if (dest_fallback == "")
- dest_fallback = s;
- option._short_opts.insert(s);
- _optmap_s[s] = &option;
+OptionParser::OptionParser()
+ : _usage(_("%prog [options]"))
+ , _add_help_option(true)
+ , _add_version_option(true)
+ , _interspersed_args(true)
+{
+}
+
+Option& OptionParser::add_option(const string& opt)
+{
+ const string tmp[1] = {opt};
+ return add_option(vector<string>(&tmp[0], &tmp[1]));
+}
+Option& OptionParser::add_option(const string& opt1, const string& opt2)
+{
+ const string tmp[2] = {opt1, opt2};
+ return add_option(vector<string>(&tmp[0], &tmp[2]));
+}
+Option& OptionParser::add_option(const string& opt1, const string& opt2, const string& opt3)
+{
+ const string tmp[3] = {opt1, opt2, opt3};
+ return add_option(vector<string>(&tmp[0], &tmp[3]));
+}
+Option& OptionParser::add_option(const vector<string>& v)
+{
+ _opts.resize(_opts.size() + 1);
+ Option& option = _opts.back();
+ string dest_fallback;
+ for (vector<string>::const_iterator it = v.begin(); it != v.end(); ++it) {
+ if (it->substr(0, 2) == "--") {
+ const string s = it->substr(2);
+ if (option.dest() == "") option.dest(str_replace(s, "-", "_"));
+ option._long_opts.insert(s);
+ _optmap_l[s] = &option;
+ } else {
+ const string s = it->substr(1, 1);
+ if (dest_fallback == "") dest_fallback = s;
+ option._short_opts.insert(s);
+ _optmap_s[s] = &option;
+ }
+ }
+ if (option.dest() == "") option.dest(dest_fallback);
+ return option;
+}
+
+OptionParser& OptionParser::add_option_group(const OptionGroup& group)
+{
+ _groups.push_back(group);
+ OptionGroup& currentGroup = _groups.back();
+
+ for (list<Option>::const_iterator oit = currentGroup._opts.begin();
+ oit != currentGroup._opts.end(); ++oit) {
+ const Option& option = *oit;
+ for (set<string>::const_iterator it = option._short_opts.begin();
+ it != option._short_opts.end(); ++it)
+ _optmap_s[*it] = &option;
+ for (set<string>::const_iterator it = option._long_opts.begin();
+ it != option._long_opts.end(); ++it)
+ _optmap_l[*it] = &option;
}
- }
- if (option.dest() == "")
- option.dest(dest_fallback);
- return option;
-}
-
-OptionParser& OptionParser::add_option_group(const OptionGroup& group) {
- _groups.push_back(group);
- OptionGroup& currentGroup = _groups.back();
-
- for (list<Option>::const_iterator oit = currentGroup._opts.begin(); oit != currentGroup._opts.end(); ++oit) {
- const Option& option = *oit;
- for (set<string>::const_iterator it = option._short_opts.begin(); it != option._short_opts.end(); ++it)
- _optmap_s[*it] = &option;
- for (set<string>::const_iterator it = option._long_opts.begin(); it != option._long_opts.end(); ++it)
- _optmap_l[*it] = &option;
- }
- return *this;
+ return *this;
}
-const Option& OptionParser::lookup_short_opt(const string& opt) const {
- optMap::const_iterator it = _optmap_s.find(opt);
- if (it == _optmap_s.end())
- error(_("no such option") + string(": -") + opt);
- return *it->second;
+const Option& OptionParser::lookup_short_opt(const string& opt) const
+{
+ optMap::const_iterator it = _optmap_s.find(opt);
+ if (it == _optmap_s.end()) error(_("no such option") + string(": -") + opt);
+ return *it->second;
}
-void OptionParser::handle_short_opt(const string& opt, const string& arg) {
+void OptionParser::handle_short_opt(const string& opt, const string& arg)
+{
- _remaining.pop_front();
- string value;
-
- const Option& option = lookup_short_opt(opt);
- if (option._nargs == 1) {
- value = arg.substr(2);
- if (value == "") {
- if (_remaining.empty())
- error("-" + opt + " " + _("option requires an argument"));
- value = _remaining.front();
- _remaining.pop_front();
+ _remaining.pop_front();
+ string value;
+
+ const Option& option = lookup_short_opt(opt);
+ if (option._nargs == 1) {
+ value = arg.substr(2);
+ if (value == "") {
+ if (_remaining.empty()) error("-" + opt + " " + _("option requires an argument"));
+ value = _remaining.front();
+ _remaining.pop_front();
+ }
+ } else {
+ if (arg.length() > 2) _remaining.push_front(string("-") + arg.substr(2));
}
- } else {
- if (arg.length() > 2)
- _remaining.push_front(string("-") + arg.substr(2));
- }
- process_opt(option, string("-") + opt, value);
+ process_opt(option, string("-") + opt, value);
}
-const Option& OptionParser::lookup_long_opt(const string& opt) const {
+const Option& OptionParser::lookup_long_opt(const string& opt) const
+{
- list<string> matching;
- for (optMap::const_iterator it = _optmap_l.begin(); it != _optmap_l.end(); ++it) {
- if (it->first.compare(0, opt.length(), opt) == 0)
- matching.push_back(it->first);
- }
- if (matching.size() > 1) {
- string x = str_join(", ", matching.begin(), matching.end());
- error(_("ambiguous option") + string(": --") + opt + " (" + x + "?)");
- }
- if (matching.size() == 0)
- error(_("no such option") + string(": --") + opt);
+ list<string> matching;
+ for (optMap::const_iterator it = _optmap_l.begin(); it != _optmap_l.end(); ++it) {
+ if (it->first.compare(0, opt.length(), opt) == 0) matching.push_back(it->first);
+ }
+ if (matching.size() > 1) {
+ string x = str_join(", ", matching.begin(), matching.end());
+ error(_("ambiguous option") + string(": --") + opt + " (" + x + "?)");
+ }
+ if (matching.size() == 0) error(_("no such option") + string(": --") + opt);
- return *_optmap_l.find(matching.front())->second;
+ return *_optmap_l.find(matching.front())->second;
}
-void OptionParser::handle_long_opt(const string& optstr) {
-
- _remaining.pop_front();
- string opt, value;
-
- size_t delim = optstr.find("=");
- if (delim != string::npos) {
- opt = optstr.substr(0, delim);
- value = optstr.substr(delim+1);
- } else
- opt = optstr;
+void OptionParser::handle_long_opt(const string& optstr)
+{
- const Option& option = lookup_long_opt(opt);
- if (option._nargs == 1 and delim == string::npos) {
- if (not _remaining.empty()) {
- value = _remaining.front();
- _remaining.pop_front();
+ _remaining.pop_front();
+ string opt, value;
+
+ size_t delim = optstr.find("=");
+ if (delim != string::npos) {
+ opt = optstr.substr(0, delim);
+ value = optstr.substr(delim + 1);
+ } else
+ opt = optstr;
+
+ const Option& option = lookup_long_opt(opt);
+ if (option._nargs == 1 and delim == string::npos) {
+ if (not _remaining.empty()) {
+ value = _remaining.front();
+ _remaining.pop_front();
+ }
}
- }
- if (option._nargs == 1 and value == "")
- error("--" + opt + " " + _("option requires an argument"));
+ if (option._nargs == 1 and value == "")
+ error("--" + opt + " " + _("option requires an argument"));
- process_opt(option, string("--") + opt, value);
+ process_opt(option, string("--") + opt, value);
}
-Values& OptionParser::parse_args(const int argc, char const* const* const argv) {
- if (prog() == "")
- prog(basename(argv[0]));
- return parse_args(&argv[1], &argv[argc]);
+Values& OptionParser::parse_args(const int argc, char const* const* const argv)
+{
+ if (prog() == "") prog(basename(argv[0]));
+ return parse_args(&argv[1], &argv[argc]);
}
-Values& OptionParser::parse_args(const vector<string>& v) {
+Values& OptionParser::parse_args(const vector<string>& v)
+{
- _remaining.assign(v.begin(), v.end());
+ _remaining.assign(v.begin(), v.end());
- if (add_version_option() and version() != "") {
- add_option("--version") .action("version") .help(_("Show program's version number and exit."));
- _opts.splice(_opts.begin(), _opts, --(_opts.end()));
- }
- if (add_help_option()) {
- add_option("-h", "--help") .action("help") .help(_("Show this help message and exit."));
- _opts.splice(_opts.begin(), _opts, --(_opts.end()));
- }
+ if (add_version_option() and version() != "") {
+ add_option("--version")
+ .action("version")
+ .help(_("Show program's version number and exit."));
+ _opts.splice(_opts.begin(), _opts, --(_opts.end()));
+ }
+ if (add_help_option()) {
+ add_option("-h", "--help").action("help").help(_("Show this help message and exit."));
+ _opts.splice(_opts.begin(), _opts, --(_opts.end()));
+ }
- while (not _remaining.empty()) {
- const string arg = _remaining.front();
+ while (not _remaining.empty()) {
+ const string arg = _remaining.front();
+
+ if (arg == "--") {
+ _remaining.pop_front();
+ break;
+ }
+
+ if (arg.substr(0, 2) == "--") {
+ handle_long_opt(arg.substr(2));
+ } else if (arg.substr(0, 1) == "-" and arg.length() > 1) {
+ handle_short_opt(arg.substr(1, 1), arg);
+ } else {
+ _remaining.pop_front();
+ _leftover.push_back(arg);
+ if (not interspersed_args()) break;
+ }
+ }
+ while (not _remaining.empty()) {
+ const string arg = _remaining.front();
+ _remaining.pop_front();
+ _leftover.push_back(arg);
+ }
- if (arg == "--") {
- _remaining.pop_front();
- break;
+ for (strMap::const_iterator it = _defaults.begin(); it != _defaults.end(); ++it) {
+ if (not _values.is_set(it->first)) _values[it->first] = it->second;
}
- if (arg.substr(0,2) == "--") {
- handle_long_opt(arg.substr(2));
- } else if (arg.substr(0,1) == "-" and arg.length() > 1) {
- handle_short_opt(arg.substr(1,1), arg);
- } else {
- _remaining.pop_front();
- _leftover.push_back(arg);
- if (not interspersed_args())
- break;
+ for (list<Option>::const_iterator it = _opts.begin(); it != _opts.end(); ++it) {
+ if (not _values.is_set(it->dest())) _values[it->dest()] = it->get_default();
}
- }
- while (not _remaining.empty()) {
- const string arg = _remaining.front();
- _remaining.pop_front();
- _leftover.push_back(arg);
- }
-
- for (strMap::const_iterator it = _defaults.begin(); it != _defaults.end(); ++it) {
- if (not _values.is_set(it->first))
- _values[it->first] = it->second;
- }
-
- for (list<Option>::const_iterator it = _opts.begin(); it != _opts.end(); ++it) {
- if (not _values.is_set(it->dest()))
- _values[it->dest()] = it->get_default();
- }
-
- for (list<OptionGroup>::iterator group_it = _groups.begin(); group_it != _groups.end(); ++group_it) {
- for (strMap::const_iterator it = group_it->_defaults.begin(); it != group_it->_defaults.end(); ++it) {
- if (not _values.is_set(it->first))
- _values[it->first] = it->second;
- }
-
- for (list<Option>::const_iterator it = group_it->_opts.begin(); it != group_it->_opts.end(); ++it) {
- if (it->get_default() != "" and not _values.is_set(it->dest()))
- _values[it->dest()] = it->get_default();
- }
- }
-
- return _values;
-}
-
-void OptionParser::process_opt(const Option& o, const string& opt, const string& value) {
- if (o.action() == "store") {
- string err = o.check_type(opt, value);
- if (err != "")
- error(err);
- _values[o.dest()] = value;
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "store_const") {
- _values[o.dest()] = o.get_const();
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "store_true") {
- _values[o.dest()] = "1";
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "store_false") {
- _values[o.dest()] = "0";
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "append") {
- string err = o.check_type(opt, value);
- if (err != "")
- error(err);
- _values[o.dest()] = value;
- _values.all(o.dest()).push_back(value);
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "append_const") {
- _values[o.dest()] = o.get_const();
- _values.all(o.dest()).push_back(o.get_const());
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "count") {
- _values[o.dest()] = str_inc(_values[o.dest()]);
- _values.is_set_by_user(o.dest(), true);
- }
- else if (o.action() == "help") {
- print_help();
- std::exit(0);
- }
- else if (o.action() == "version") {
- print_version();
- std::exit(0);
- }
- else if (o.action() == "callback" && o.callback()) {
- (*o.callback())(o, opt, value, *this);
- }
-}
-
-string OptionParser::format_option_help(unsigned int indent /* = 2 */) const {
- stringstream ss;
-
- if (_opts.empty())
- return ss.str();
- for (list<Option>::const_iterator it = _opts.begin(); it != _opts.end(); ++it) {
- if (it->help() != SUPPRESS_HELP)
- ss << it->format_help(indent);
- }
+ for (list<OptionGroup>::iterator group_it = _groups.begin(); group_it != _groups.end();
+ ++group_it) {
+ for (strMap::const_iterator it = group_it->_defaults.begin();
+ it != group_it->_defaults.end(); ++it) {
+ if (not _values.is_set(it->first)) _values[it->first] = it->second;
+ }
+
+ for (list<Option>::const_iterator it = group_it->_opts.begin(); it != group_it->_opts.end();
+ ++it) {
+ if (it->get_default() != "" and not _values.is_set(it->dest()))
+ _values[it->dest()] = it->get_default();
+ }
+ }
- return ss.str();
+ return _values;
+}
+
+void OptionParser::process_opt(const Option& o, const string& opt, const string& value)
+{
+ if (o.action() == "store") {
+ string err = o.check_type(opt, value);
+ if (err != "") error(err);
+ _values[o.dest()] = value;
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "store_const") {
+ _values[o.dest()] = o.get_const();
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "store_true") {
+ _values[o.dest()] = "1";
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "store_false") {
+ _values[o.dest()] = "0";
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "append") {
+ string err = o.check_type(opt, value);
+ if (err != "") error(err);
+ _values[o.dest()] = value;
+ _values.all(o.dest()).push_back(value);
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "append_const") {
+ _values[o.dest()] = o.get_const();
+ _values.all(o.dest()).push_back(o.get_const());
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "count") {
+ _values[o.dest()] = str_inc(_values[o.dest()]);
+ _values.is_set_by_user(o.dest(), true);
+ } else if (o.action() == "help") {
+ print_help();
+ std::exit(0);
+ } else if (o.action() == "version") {
+ print_version();
+ std::exit(0);
+ } else if (o.action() == "callback" && o.callback()) {
+ (*o.callback())(o, opt, value, *this);
+ }
}
-string OptionParser::format_help() const {
- stringstream ss;
+string OptionParser::format_option_help(unsigned int indent /* = 2 */) const
+{
+ stringstream ss;
- if (usage() != SUPPRESS_USAGE)
- ss << get_usage() << endl;
+ if (_opts.empty()) return ss.str();
- if (description() != "")
- ss << str_format(description(), 0, cols()) << endl;
+ for (list<Option>::const_iterator it = _opts.begin(); it != _opts.end(); ++it) {
+ if (it->help() != SUPPRESS_HELP) ss << it->format_help(indent);
+ }
- ss << _("Options") << ":" << endl;
- ss << format_option_help();
+ return ss.str();
+}
- for (list<OptionGroup>::const_iterator it = _groups.begin(); it != _groups.end(); ++it) {
- const OptionGroup& group = *it;
- ss << endl << " " << group.title() << ":" << endl;
- if (group.group_description() != "")
- ss << str_format(group.group_description(), 4, cols()) << endl;
- ss << group.format_option_help(4);
- }
+string OptionParser::format_help() const
+{
+ stringstream ss;
- if (epilog() != "")
- ss << endl << str_format(epilog(), 0, cols());
+ if (usage() != SUPPRESS_USAGE) ss << get_usage() << endl;
- return ss.str();
-}
-void OptionParser::print_help() const {
- cout << format_help();
-}
+ if (description() != "") ss << str_format(description(), 0, cols()) << endl;
-void OptionParser::set_usage(const string& u) {
- string lower = u;
- transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
- if (lower.compare(0, 7, "usage: ") == 0)
- _usage = u.substr(7);
- else
- _usage = u;
-}
-string OptionParser::format_usage(const string& u) const {
- stringstream ss;
- ss << _("Usage") << ": " << u << endl;
- return ss.str();
+ ss << _("Options") << ":" << endl;
+ ss << format_option_help();
+
+ for (list<OptionGroup>::const_iterator it = _groups.begin(); it != _groups.end(); ++it) {
+ const OptionGroup& group = *it;
+ ss << endl << " " << group.title() << ":" << endl;
+ if (group.group_description() != "")
+ ss << str_format(group.group_description(), 4, cols()) << endl;
+ ss << group.format_option_help(4);
+ }
+
+ if (epilog() != "") ss << endl << str_format(epilog(), 0, cols());
+
+ return ss.str();
}
-string OptionParser::get_usage() const {
- if (usage() == SUPPRESS_USAGE)
- return string("");
- return format_usage(str_replace(usage(), "%prog", prog()));
+void OptionParser::print_help() const { cout << format_help(); }
+
+void OptionParser::set_usage(const string& u)
+{
+ string lower = u;
+ transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+ if (lower.compare(0, 7, "usage: ") == 0)
+ _usage = u.substr(7);
+ else
+ _usage = u;
+}
+string OptionParser::format_usage(const string& u) const
+{
+ stringstream ss;
+ ss << _("Usage") << ": " << u << endl;
+ return ss.str();
}
-void OptionParser::print_usage(ostream& out) const {
- string u = get_usage();
- if (u != "")
- out << u << endl;
+string OptionParser::get_usage() const
+{
+ if (usage() == SUPPRESS_USAGE) return string("");
+ return format_usage(str_replace(usage(), "%prog", prog()));
}
-void OptionParser::print_usage() const {
- print_usage(cout);
+void OptionParser::print_usage(ostream& out) const
+{
+ string u = get_usage();
+ if (u != "") out << u << endl;
}
+void OptionParser::print_usage() const { print_usage(cout); }
-string OptionParser::get_version() const {
- return str_replace(_version, "%prog", prog());
-}
-void OptionParser::print_version(ostream& out) const {
- out << get_version() << endl;
-}
-void OptionParser::print_version() const {
- print_version(cout);
-}
+string OptionParser::get_version() const { return str_replace(_version, "%prog", prog()); }
+void OptionParser::print_version(ostream& out) const { out << get_version() << endl; }
+void OptionParser::print_version() const { print_version(cout); }
-void OptionParser::exit() const {
- std::exit(2);
-}
-void OptionParser::error(const string& msg) const {
- print_usage(cerr);
- cerr << prog() << ": " << _("error") << ": " << msg << endl;
- exit();
+void OptionParser::exit() const { std::exit(2); }
+void OptionParser::error(const string& msg) const
+{
+ print_usage(cerr);
+ cerr << prog() << ": " << _("error") << ": " << msg << endl;
+ exit();
}
////////// } class OptionParser //////////
////////// class Values { //////////
-void Values::is_set_by_user(const string& d, bool yes) {
- if (yes)
- _userSet.insert(d);
- else
- _userSet.erase(d);
+void Values::is_set_by_user(const string& d, bool yes)
+{
+ if (yes)
+ _userSet.insert(d);
+ else
+ _userSet.erase(d);
}
////////// } class Values //////////
////////// class Option { //////////
-string Option::check_type(const string& opt, const string& val) const {
- istringstream ss(val);
- stringstream err;
-
- if (type() == "int" || type() == "long") {
- long t;
- if (not (ss >> t))
- err << _("option") << " " << opt << ": " << _("invalid integer value") << ": '" << val << "'";
- }
- else if (type() == "float" || type() == "double") {
- double t;
- if (not (ss >> t) && ss.str() != "NaN" && ss.str() != "nan" )
- err << _("option") << " " << opt << ": " << _("invalid floating-point value") << ": '" << val << "'";
- }
- else if (type() == "choice") {
- if (find(choices().begin(), choices().end(), val) == choices().end()) {
- list<string> tmp = choices();
- transform(tmp.begin(), tmp.end(), tmp.begin(), str_wrap("'"));
- err << _("option") << " " << opt << ": " << _("invalid choice") << ": '" << val << "'"
- << " (" << _("choose from") << " " << str_join(", ", tmp.begin(), tmp.end()) << ")";
+string Option::check_type(const string& opt, const string& val) const
+{
+ istringstream ss(val);
+ stringstream err;
+
+ if (type() == "int" || type() == "long") {
+ long t;
+ if (not(ss >> t))
+ err << _("option") << " " << opt << ": " << _("invalid integer value") << ": '" << val
+ << "'";
+ } else if (type() == "float" || type() == "double") {
+ double t;
+ if (not(ss >> t) && ss.str() != "NaN" && ss.str() != "nan")
+ err << _("option") << " " << opt << ": " << _("invalid floating-point value") << ": '"
+ << val << "'";
+ } else if (type() == "choice") {
+ if (find(choices().begin(), choices().end(), val) == choices().end()) {
+ list<string> tmp = choices();
+ transform(tmp.begin(), tmp.end(), tmp.begin(), str_wrap("'"));
+ err << _("option") << " " << opt << ": " << _("invalid choice") << ": '" << val << "'"
+ << " (" << _("choose from") << " " << str_join(", ", tmp.begin(), tmp.end()) << ")";
+ }
+ } else if (type() == "complex") {
+ complex<double> t;
+ if (not(ss >> t))
+ err << _("option") << " " << opt << ": " << _("invalid complex value") << ": '" << val
+ << "'";
+ }
+
+ return err.str();
+}
+
+string Option::format_option_help(unsigned int indent /* = 2 */) const
+{
+
+ string mvar_short, mvar_long;
+ if (nargs() == 1) {
+ string mvar = metavar();
+ if (mvar == "") {
+ mvar = type();
+ transform(mvar.begin(), mvar.end(), mvar.begin(), ::toupper);
+ }
+ mvar_short = " " + mvar;
+ mvar_long = "=" + mvar;
+ }
+
+ stringstream ss;
+ ss << string(indent, ' ');
+
+ if (not _short_opts.empty()) {
+ ss << str_join_trans(", ", _short_opts.begin(), _short_opts.end(),
+ str_wrap("-", mvar_short));
+ if (not _long_opts.empty()) ss << ", ";
}
- }
- else if (type() == "complex") {
- complex<double> t;
- if (not (ss >> t))
- err << _("option") << " " << opt << ": " << _("invalid complex value") << ": '" << val << "'";
- }
-
- return err.str();
-}
-
-string Option::format_option_help(unsigned int indent /* = 2 */) const {
-
- string mvar_short, mvar_long;
- if (nargs() == 1) {
- string mvar = metavar();
- if (mvar == "") {
- mvar = type();
- transform(mvar.begin(), mvar.end(), mvar.begin(), ::toupper);
- }
- mvar_short = " " + mvar;
- mvar_long = "=" + mvar;
- }
-
- stringstream ss;
- ss << string(indent, ' ');
-
- if (not _short_opts.empty()) {
- ss << str_join_trans(", ", _short_opts.begin(), _short_opts.end(), str_wrap("-", mvar_short));
if (not _long_opts.empty())
- ss << ", ";
- }
- if (not _long_opts.empty())
- ss << str_join_trans(", ", _long_opts.begin(), _long_opts.end(), str_wrap("--", mvar_long));
-
- return ss.str();
-}
-
-string Option::format_help(unsigned int indent /* = 2 */) const {
- stringstream ss;
- string h = format_option_help(indent);
- unsigned int width = cols();
- unsigned int opt_width = min(width*3/10, 36u);
- bool indent_first = false;
- ss << h;
- // if the option list is too long, start a new paragraph
- if (h.length() >= (opt_width-1)) {
- ss << endl;
- indent_first = true;
- } else {
- ss << string(opt_width - h.length(), ' ');
- if (help() == "")
- ss << endl;
- }
- if (help() != "") {
- string help_str = (get_default() != "") ? str_replace(help(), "%default", get_default()) : help();
- ss << str_format(help_str, opt_width, width, indent_first);
- }
- return ss.str();
-}
-
-Option& Option::action(const string& a) {
- _action = a;
- if (a == "store_true")
- {
- _default = "0";
- nargs(0);
- }
- else if (a == "store_false")
- {
- _default = "1";
- nargs(0);
- }
- else if (a == "store_const" || a == "append_const" || a == "count" || a == "help" || a == "version")
- {
- nargs(0);
- }
- return *this;
+ ss << str_join_trans(", ", _long_opts.begin(), _long_opts.end(), str_wrap("--", mvar_long));
+
+ return ss.str();
}
-////////// } class Option //////////
+string Option::format_help(unsigned int indent /* = 2 */) const
+{
+ stringstream ss;
+ string h = format_option_help(indent);
+ unsigned int width = cols();
+ unsigned int opt_width = min(width * 3 / 10, 36u);
+ bool indent_first = false;
+ ss << h;
+ // if the option list is too long, start a new paragraph
+ if (h.length() >= (opt_width - 1)) {
+ ss << endl;
+ indent_first = true;
+ } else {
+ ss << string(opt_width - h.length(), ' ');
+ if (help() == "") ss << endl;
+ }
+ if (help() != "") {
+ string help_str =
+ (get_default() != "") ? str_replace(help(), "%default", get_default()) : help();
+ ss << str_format(help_str, opt_width, width, indent_first);
+ }
+ return ss.str();
+}
+
+Option& Option::action(const string& a)
+{
+ _action = a;
+ if (a == "store_true") {
+ _default = "0";
+ nargs(0);
+ } else if (a == "store_false") {
+ _default = "1";
+ nargs(0);
+ } else if (a == "store_const" || a == "append_const" || a == "count" || a == "help" ||
+ a == "version") {
+ nargs(0);
+ }
+ return *this;
+}
+////////// } class Option //////////
}
diff --git a/third-party/cpp-optparse/OptionParser.h b/third-party/cpp-optparse/OptionParser.h
index 5e316a1..f1f5052 100644
--- a/third-party/cpp-optparse/OptionParser.h
+++ b/third-party/cpp-optparse/OptionParser.h
@@ -82,26 +82,30 @@ class Values;
class Value;
class Callback;
-typedef std::map<std::string,std::string> strMap;
-typedef std::map<std::string,std::list<std::string> > lstMap;
-typedef std::map<std::string,Option const*> optMap;
+typedef std::map<std::string, std::string> strMap;
+typedef std::map<std::string, std::list<std::string> > lstMap;
+typedef std::map<std::string, Option const*> optMap;
-const char* const SUPPRESS_HELP = "SUPPRESS" "HELP";
-const char* const SUPPRESS_USAGE = "SUPPRESS" "USAGE";
+const char* const SUPPRESS_HELP =
+ "SUPPRESS"
+ "HELP";
+const char* const SUPPRESS_USAGE =
+ "SUPPRESS"
+ "USAGE";
//Exception classes for error conditions
-class InvalidValueCast : public std::runtime_error {
- public:
+class InvalidValueCast : public std::runtime_error
+{
+public:
InvalidValueCast() : std::runtime_error("invalid cast of Value") {}
};
-class InvalidOption : public std::runtime_error {
- public:
+class InvalidOption : public std::runtime_error
+{
+public:
InvalidOption() : std::runtime_error("invalid Option") {}
};
-
-
namespace {
template <typename T>
@@ -131,52 +135,53 @@ T floatingPointConvert(bool valid, const std::string& s)
throw InvalidValueCast();
}
-} // anon namespace
-
-
+} // anon namespace
//! Class for automatic conversion from string -> anytype
-class Value {
- public:
+class Value
+{
+public:
Value() : str(), valid(false) {}
Value(const std::string& v) : str(v), valid(true) {}
- operator const char*() { return str.c_str(); }
- operator bool() { return integralConvert<bool>(valid, str); }
- operator bool() const { return integralConvert<bool>(valid, str); }
- operator short() { return integralConvert<short>(valid, str); }
- operator short() const { return integralConvert<short>(valid, str); }
- operator unsigned short() { return integralConvert<unsigned short>(valid, str); }
+ operator const char*() { return str.c_str(); }
+ operator bool() { return integralConvert<bool>(valid, str); }
+ operator bool() const { return integralConvert<bool>(valid, str); }
+ operator short() { return integralConvert<short>(valid, str); }
+ operator short() const { return integralConvert<short>(valid, str); }
+ operator unsigned short() { return integralConvert<unsigned short>(valid, str); }
operator unsigned short() const { return integralConvert<unsigned short>(valid, str); }
- operator int() { return integralConvert<int>(valid, str); }
- operator int() const { return integralConvert<int>(valid, str); }
- operator unsigned int() { return integralConvert<unsigned int>(valid, str); }
- operator unsigned int() const { return integralConvert<unsigned int>(valid, str); }
- operator long() { return integralConvert<long>(valid, str); }
- operator long() const { return integralConvert<long>(valid, str); }
- operator unsigned long() { return integralConvert<unsigned long>(valid, str); }
- operator unsigned long() const { return integralConvert<unsigned long>(valid, str); }
- operator float() { return floatingPointConvert<float>(valid, str); }
- operator float() const { return floatingPointConvert<float>(valid, str); }
- operator double() { return floatingPointConvert<double>(valid, str); }
- operator double() const { return floatingPointConvert<double>(valid, str); }
- operator long double() { return floatingPointConvert<long double>(valid, str); }
- operator long double() const { return floatingPointConvert<long double>(valid, str); }
+ operator int() { return integralConvert<int>(valid, str); }
+ operator int() const { return integralConvert<int>(valid, str); }
+ operator unsigned int() { return integralConvert<unsigned int>(valid, str); }
+ operator unsigned int() const { return integralConvert<unsigned int>(valid, str); }
+ operator long() { return integralConvert<long>(valid, str); }
+ operator long() const { return integralConvert<long>(valid, str); }
+ operator unsigned long() { return integralConvert<unsigned long>(valid, str); }
+ operator unsigned long() const { return integralConvert<unsigned long>(valid, str); }
+ operator float() { return floatingPointConvert<float>(valid, str); }
+ operator float() const { return floatingPointConvert<float>(valid, str); }
+ operator double() { return floatingPointConvert<double>(valid, str); }
+ operator double() const { return floatingPointConvert<double>(valid, str); }
+ operator long double() { return floatingPointConvert<long double>(valid, str); }
+ operator long double() const { return floatingPointConvert<long double>(valid, str); }
private:
const std::string str;
bool valid;
};
-class Values {
- public:
+class Values
+{
+public:
Values() : _map() {}
- const std::string& operator[] (const std::string& d) const {
+ const std::string& operator[](const std::string& d) const
+ {
strMap::const_iterator it = _map.find(d);
if (it != _map.end()) return it->second;
throw InvalidOption();
}
- std::string& operator[] (const std::string& d) { return _map[d]; }
+ std::string& operator[](const std::string& d) { return _map[d]; }
bool is_set(const std::string& d) const { return _map.find(d) != _map.end(); }
bool is_set_by_user(const std::string& d) const { return _userSet.find(d) != _userSet.end(); }
void is_set_by_user(const std::string& d, bool yes);
@@ -185,31 +190,73 @@ class Values {
typedef std::list<std::string>::iterator iterator;
typedef std::list<std::string>::const_iterator const_iterator;
std::list<std::string>& all(const std::string& d) { return _appendMap[d]; }
- const std::list<std::string>& all(const std::string& d) const { return _appendMap.find(d)->second; }
+ const std::list<std::string>& all(const std::string& d) const
+ {
+ return _appendMap.find(d)->second;
+ }
- private:
+private:
strMap _map;
lstMap _appendMap;
std::set<std::string> _userSet;
};
-class OptionParser {
- public:
+class OptionParser
+{
+public:
OptionParser();
virtual ~OptionParser() {}
- OptionParser& usage(const std::string& u) { set_usage(u); return *this; }
- OptionParser& version(const std::string& v) { _version = v; return *this; }
- OptionParser& description(const std::string& d) { _description = d; return *this; }
- OptionParser& add_help_option(bool h) { _add_help_option = h; return *this; }
- OptionParser& add_version_option(bool v) { _add_version_option = v; return *this; }
- OptionParser& prog(const std::string& p) { _prog = p; return *this; }
- OptionParser& epilog(const std::string& e) { _epilog = e; return *this; }
- OptionParser& set_defaults(const std::string& dest, const std::string& val) {
- _defaults[dest] = val; return *this;
+ OptionParser& usage(const std::string& u)
+ {
+ set_usage(u);
+ return *this;
+ }
+ OptionParser& version(const std::string& v)
+ {
+ _version = v;
+ return *this;
+ }
+ OptionParser& description(const std::string& d)
+ {
+ _description = d;
+ return *this;
+ }
+ OptionParser& add_help_option(bool h)
+ {
+ _add_help_option = h;
+ return *this;
+ }
+ OptionParser& add_version_option(bool v)
+ {
+ _add_version_option = v;
+ return *this;
+ }
+ OptionParser& prog(const std::string& p)
+ {
+ _prog = p;
+ return *this;
+ }
+ OptionParser& epilog(const std::string& e)
+ {
+ _epilog = e;
+ return *this;
+ }
+ OptionParser& set_defaults(const std::string& dest, const std::string& val)
+ {
+ _defaults[dest] = val;
+ return *this;
+ }
+ OptionParser& enable_interspersed_args()
+ {
+ _interspersed_args = true;
+ return *this;
+ }
+ OptionParser& disable_interspersed_args()
+ {
+ _interspersed_args = false;
+ return *this;
}
- OptionParser& enable_interspersed_args() { _interspersed_args = true; return *this; }
- OptionParser& disable_interspersed_args() { _interspersed_args = false; return *this; }
OptionParser& add_option_group(const OptionGroup& group);
const std::string& usage() const { return _usage; }
@@ -228,14 +275,16 @@ class OptionParser {
Values& parse_args(int argc, char const* const* argv);
Values& parse_args(const std::vector<std::string>& args);
- template<typename InputIterator>
- Values& parse_args(InputIterator begin, InputIterator end) {
- return parse_args(std::vector<std::string>(begin, end));
+ template <typename InputIterator>
+ Values& parse_args(InputIterator begin, InputIterator end)
+ {
+ return parse_args(std::vector<std::string>(begin, end));
}
const std::list<std::string>& args() const { return _leftover; }
- std::vector<std::string> args() {
- return std::vector<std::string>(_leftover.begin(), _leftover.end());
+ std::vector<std::string> args()
+ {
+ return std::vector<std::string>(_leftover.begin(), _leftover.end());
}
std::string format_help() const;
@@ -254,7 +303,7 @@ class OptionParser {
void error(const std::string& msg) const;
void exit() const;
- private:
+private:
const Option& lookup_short_opt(const std::string& opt) const;
const Option& lookup_long_opt(const std::string& opt) const;
@@ -286,42 +335,95 @@ class OptionParser {
std::list<std::string> _leftover;
};
-class OptionGroup : public OptionParser {
- public:
- OptionGroup(const OptionParser&, const std::string& t, const std::string& d = "") :
- _title(t), _group_description(d) {}
+class OptionGroup : public OptionParser
+{
+public:
+ OptionGroup(const OptionParser&, const std::string& t, const std::string& d = "")
+ : _title(t), _group_description(d)
+ {
+ }
virtual ~OptionGroup() {}
- OptionGroup& title(const std::string& t) { _title = t; return *this; }
- OptionGroup& group_description(const std::string& d) { _group_description = d; return *this; }
+ OptionGroup& title(const std::string& t)
+ {
+ _title = t;
+ return *this;
+ }
+ OptionGroup& group_description(const std::string& d)
+ {
+ _group_description = d;
+ return *this;
+ }
const std::string& title() const { return _title; }
const std::string& group_description() const { return _group_description; }
- private:
+private:
std::string _title;
std::string _group_description;
};
-class Option {
- public:
+class Option
+{
+public:
Option() : _action("store"), _type("string"), _nargs(1), _callback(0) {}
virtual ~Option() {}
Option& action(const std::string& a);
- Option& type(const std::string& t) { _type = t; return *this; }
- Option& dest(const std::string& d) { _dest = d; return *this; }
- Option& set_default(const std::string& d) { _default = d; return *this; }
- template<typename T>
- Option& set_default(T t) { std::ostringstream ss; ss << t; _default = ss.str(); return *this; }
- Option& nargs(size_t n) { _nargs = n; return *this; }
- Option& set_const(const std::string& c) { _const = c; return *this; }
- template<typename InputIterator>
- Option& choices(InputIterator begin, InputIterator end) {
- _choices.assign(begin, end); type("choice"); return *this;
+ Option& type(const std::string& t)
+ {
+ _type = t;
+ return *this;
+ }
+ Option& dest(const std::string& d)
+ {
+ _dest = d;
+ return *this;
+ }
+ Option& set_default(const std::string& d)
+ {
+ _default = d;
+ return *this;
+ }
+ template <typename T>
+ Option& set_default(T t)
+ {
+ std::ostringstream ss;
+ ss << t;
+ _default = ss.str();
+ return *this;
+ }
+ Option& nargs(size_t n)
+ {
+ _nargs = n;
+ return *this;
+ }
+ Option& set_const(const std::string& c)
+ {
+ _const = c;
+ return *this;
+ }
+ template <typename InputIterator>
+ Option& choices(InputIterator begin, InputIterator end)
+ {
+ _choices.assign(begin, end);
+ type("choice");
+ return *this;
+ }
+ Option& help(const std::string& h)
+ {
+ _help = h;
+ return *this;
+ }
+ Option& metavar(const std::string& m)
+ {
+ _metavar = m;
+ return *this;
+ }
+ Option& callback(Callback& c)
+ {
+ _callback = &c;
+ return *this;
}
- Option& help(const std::string& h) { _help = h; return *this; }
- Option& metavar(const std::string& m) { _metavar = m; return *this; }
- Option& callback(Callback& c) { _callback = &c; return *this; }
const std::string& action() const { return _action; }
const std::string& type() const { return _type; }
@@ -334,7 +436,7 @@ class Option {
const std::string& metavar() const { return _metavar; }
Callback* callback() const { return _callback; }
- private:
+private:
std::string check_type(const std::string& opt, const std::string& val) const;
std::string format_option_help(unsigned int indent = 2) const;
std::string format_help(unsigned int indent = 2) const;
@@ -356,12 +458,13 @@ class Option {
friend class OptionParser;
};
-class Callback {
+class Callback
+{
public:
- virtual void operator() (const Option& option, const std::string& opt, const std::string& val, const OptionParser& parser) = 0;
- virtual ~Callback() {}
+ virtual void operator()(const Option& option, const std::string& opt, const std::string& val,
+ const OptionParser& parser) = 0;
+ virtual ~Callback() {}
};
-
}
#endif
diff --git a/third-party/cpp-optparse/test.cpp b/third-party/cpp-optparse/test.cpp
index b0a85cc..bbbbe10 100644
--- a/third-party/cpp-optparse/test.cpp
+++ b/third-party/cpp-optparse/test.cpp
@@ -1,153 +1,188 @@
#include "OptionParser.h"
+#include <algorithm>
+#include <complex>
#include <iostream>
#include <sstream>
#include <string>
-#include <complex>
-#include <algorithm>
using namespace std;
using namespace optparse;
-class Output {
+class Output
+{
public:
- Output(const string& d) : delim(d), first(true) {}
- void operator() (const string& s) {
- if (first)
- first = false;
- else
- cout << delim;
- cout << s;
- }
- ~Output() { cout << endl; }
- const string& delim;
- bool first;
+ Output(const string& d) : delim(d), first(true) {}
+ void operator()(const string& s)
+ {
+ if (first)
+ first = false;
+ else
+ cout << delim;
+ cout << s;
+ }
+ ~Output() { cout << endl; }
+ const string& delim;
+ bool first;
};
-class MyCallback : public optparse::Callback {
+class MyCallback : public optparse::Callback
+{
public:
- MyCallback() : counter(0) {}
- void operator() (const Option& option, const string& opt, const string& val, const OptionParser& parser) {
- counter++;
- cout << "--- MyCallback --- " << counter << ". time called" << endl;
- cout << "--- MyCallback --- option.action(): " << option.action() << endl;
- cout << "--- MyCallback --- opt: " << opt << endl;
- cout << "--- MyCallback --- val: " << val << endl;
- cout << "--- MyCallback --- parser.usage(): " << parser.usage() << endl;
- cout << endl;
- }
- int counter;
+ MyCallback() : counter(0) {}
+ void operator()(const Option& option, const string& opt, const string& val,
+ const OptionParser& parser)
+ {
+ counter++;
+ cout << "--- MyCallback --- " << counter << ". time called" << endl;
+ cout << "--- MyCallback --- option.action(): " << option.action() << endl;
+ cout << "--- MyCallback --- opt: " << opt << endl;
+ cout << "--- MyCallback --- val: " << val << endl;
+ cout << "--- MyCallback --- parser.usage(): " << parser.usage() << endl;
+ cout << endl;
+ }
+ int counter;
};
-int main(int argc, char *argv[])
+int main(int argc, char* argv[])
{
#ifndef DISABLE_USAGE
- const string usage = "usage: %prog [OPTION]... DIR [FILE]...";
+ const string usage = "usage: %prog [OPTION]... DIR [FILE]...";
#else
- const string usage = SUPPRESS_USAGE;
+ const string usage = SUPPRESS_USAGE;
#endif
- const string version = "%prog 1.0\nCopyright (C) 2010 Johannes Weißl\n"
- "License GPLv3+: GNU GPL version 3 or later "
- "<http://gnu.org/licenses/gpl.html>.\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.";
- const string desc = "Lorem ipsum dolor sit amet, consectetur adipisicing"
- " elit, sed do eiusmod tempor incididunt ut labore et dolore magna"
- " aliqua.\nUt enim ad minim veniam, quis nostrud exercitation ullamco"
- " laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor"
- " in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla"
- " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa"
- " qui officia deserunt mollit anim id est laborum.";
- const string epilog = "Sed ut perspiciatis unde omnis iste natus error sit"
- " voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque"
- " ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae"
- " dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit"
- " aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos"
- " qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui"
- " dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia"
- " non numquam eius modi tempora incidunt ut labore et dolore magnam"
- " aliquam quaerat voluptatem.";
+ const string version =
+ "%prog 1.0\nCopyright (C) 2010 Johannes Weißl\n"
+ "License GPLv3+: GNU GPL version 3 or later "
+ "<http://gnu.org/licenses/gpl.html>.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.";
+ const string desc =
+ "Lorem ipsum dolor sit amet, consectetur adipisicing"
+ " elit, sed do eiusmod tempor incididunt ut labore et dolore magna"
+ " aliqua.\nUt enim ad minim veniam, quis nostrud exercitation ullamco"
+ " laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor"
+ " in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla"
+ " pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa"
+ " qui officia deserunt mollit anim id est laborum.";
+ const string epilog =
+ "Sed ut perspiciatis unde omnis iste natus error sit"
+ " voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque"
+ " ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae"
+ " dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit"
+ " aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos"
+ " qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui"
+ " dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia"
+ " non numquam eius modi tempora incidunt ut labore et dolore magnam"
+ " aliquam quaerat voluptatem.";
- OptionParser parser = OptionParser()
- .usage(usage)
- .version(version)
- .description(desc)
- .epilog(epilog)
+ OptionParser parser = OptionParser()
+ .usage(usage)
+ .version(version)
+ .description(desc)
+ .epilog(epilog)
#ifdef DISABLE_INTERSPERSED_ARGS
- .disable_interspersed_args()
+ .disable_interspersed_args()
#endif
- ;
+ ;
- parser.set_defaults("verbosity", "50");
- parser.set_defaults("no_clear", "0");
+ parser.set_defaults("verbosity", "50");
+ parser.set_defaults("no_clear", "0");
- // test all actions
- parser.add_option("--clear") .action("store_false") .dest("no_clear") .help("clear (default)");
- parser.add_option("--no-clear") .action("store_true") .help("not clear");
- parser.add_option("--string")
- .help("This is a really long text... very long indeed! It must be wrapped on normal terminals.");
- parser.add_option("-x", "--clause", "--sentence") .metavar("SENTENCE") .set_default("I'm a sentence")
- .help("This is a really long text... very long indeed! It must be wrapped on normal terminals. "
- "Also it should appear not on the same line as the option.");
- parser.add_option("-k") .action("count") .help("how many times?");
- parser.add_option("-v", "--verbose") .action("store_const") .set_const("100") .dest("verbosity") .help("be verbose!");
- parser.add_option("-s", "--silent") .action("store_const") .set_const("0") .dest("verbosity") .help("be silent!");
- parser.add_option("-n", "--number") .type("int") .set_default("1") .metavar("NUM") .help("number of files (default: %default)");
- parser.add_option("-H") .action("help") .help("alternative help");
- parser.add_option("-V") .action("version") .help("alternative version");
- parser.add_option("-i", "--int") .action("store") .type("int") .set_default(3) .help("default: %default");
- parser.add_option("-f", "--float") .action("store") .type("float") .set_default(5.3) .help("default: %default");
- parser.add_option("-c", "--complex") .action("store") .type("complex");
- char const* const choices[] = { "foo", "bar", "baz" };
- parser.add_option("-C", "--choices") .choices(&choices[0], &choices[3]);
- parser.add_option("-m", "--more") .action("append");
- parser.add_option("--more-milk") .action("append_const") .set_const("milk");
- parser.add_option("--hidden") .help(SUPPRESS_HELP);
+ // test all actions
+ parser.add_option("--clear").action("store_false").dest("no_clear").help("clear (default)");
+ parser.add_option("--no-clear").action("store_true").help("not clear");
+ parser.add_option("--string")
+ .help(
+ "This is a really long text... very long indeed! It must be wrapped on normal "
+ "terminals.");
+ parser.add_option("-x", "--clause", "--sentence")
+ .metavar("SENTENCE")
+ .set_default("I'm a sentence")
+ .help(
+ "This is a really long text... very long indeed! It must be wrapped on normal "
+ "terminals. "
+ "Also it should appear not on the same line as the option.");
+ parser.add_option("-k").action("count").help("how many times?");
+ parser.add_option("-v", "--verbose")
+ .action("store_const")
+ .set_const("100")
+ .dest("verbosity")
+ .help("be verbose!");
+ parser.add_option("-s", "--silent")
+ .action("store_const")
+ .set_const("0")
+ .dest("verbosity")
+ .help("be silent!");
+ parser.add_option("-n", "--number")
+ .type("int")
+ .set_default("1")
+ .metavar("NUM")
+ .help("number of files (default: %default)");
+ parser.add_option("-H").action("help").help("alternative help");
+ parser.add_option("-V").action("version").help("alternative version");
+ parser.add_option("-i", "--int")
+ .action("store")
+ .type("int")
+ .set_default(3)
+ .help("default: %default");
+ parser.add_option("-f", "--float")
+ .action("store")
+ .type("float")
+ .set_default(5.3)
+ .help("default: %default");
+ parser.add_option("-c", "--complex").action("store").type("complex");
+ char const* const choices[] = {"foo", "bar", "baz"};
+ parser.add_option("-C", "--choices").choices(&choices[0], &choices[3]);
+ parser.add_option("-m", "--more").action("append");
+ parser.add_option("--more-milk").action("append_const").set_const("milk");
+ parser.add_option("--hidden").help(SUPPRESS_HELP);
- MyCallback mc;
- parser.add_option("-K", "--callback") .action("callback") .callback(mc) .help("callback test");
+ MyCallback mc;
+ parser.add_option("-K", "--callback").action("callback").callback(mc).help("callback test");
- OptionGroup group = OptionGroup(parser, "Dangerous Options",
- "Caution: use these options at your own risk. "
- "It is believed that some of them bite.");
- group.add_option("-g") .action("store_true") .help("Group option.") .set_default("0");
- parser.add_option_group(group);
+ OptionGroup group = OptionGroup(parser, "Dangerous Options",
+ "Caution: use these options at your own risk. "
+ "It is believed that some of them bite.");
+ group.add_option("-g").action("store_true").help("Group option.").set_default("0");
+ parser.add_option_group(group);
- Values& options = parser.parse_args(argc, argv);
- vector<string> args = parser.args();
+ Values& options = parser.parse_args(argc, argv);
+ vector<string> args = parser.args();
- cout << "clear: " << (options.get("no_clear") ? "false" : "true") << endl;
- cout << "string: " << options["string"] << endl;
- cout << "clause: " << options["clause"] << endl;
- cout << "k: " << options["k"] << endl;
- cout << "verbosity: " << options["verbosity"] << endl;
- cout << "number: " << (int) options.get("number") << endl;
- cout << "int: " << (int) options.get("int") << endl;
- cout << "float: " << (float) options.get("float") << endl;
- complex<double> c = 0;
- if (options.is_set("complex")) {
- stringstream ss;
- ss << options["complex"];
- ss >> c;
- }
- cout << "complex: " << c << endl;
- cout << "choices: " << (const char*) options.get("choices") << endl;
- cout << "more: ";
- for_each(options.all("more").begin(), options.all("more").end(), Output(", "));
- cout << "more_milk: ";
- {
- Output out(", ");
- for (Values::iterator it = options.all("more_milk").begin(); it != options.all("more_milk").end(); ++it)
- out(*it);
- }
- cout << "hidden: " << options["hidden"] << endl;
- cout << "group: " << (options.get("g") ? "true" : "false") << endl;
+ cout << "clear: " << (options.get("no_clear") ? "false" : "true") << endl;
+ cout << "string: " << options["string"] << endl;
+ cout << "clause: " << options["clause"] << endl;
+ cout << "k: " << options["k"] << endl;
+ cout << "verbosity: " << options["verbosity"] << endl;
+ cout << "number: " << (int)options.get("number") << endl;
+ cout << "int: " << (int)options.get("int") << endl;
+ cout << "float: " << (float)options.get("float") << endl;
+ complex<double> c = 0;
+ if (options.is_set("complex")) {
+ stringstream ss;
+ ss << options["complex"];
+ ss >> c;
+ }
+ cout << "complex: " << c << endl;
+ cout << "choices: " << (const char*)options.get("choices") << endl;
+ cout << "more: ";
+ for_each(options.all("more").begin(), options.all("more").end(), Output(", "));
+ cout << "more_milk: ";
+ {
+ Output out(", ");
+ for (Values::iterator it = options.all("more_milk").begin();
+ it != options.all("more_milk").end(); ++it)
+ out(*it);
+ }
+ cout << "hidden: " << options["hidden"] << endl;
+ cout << "group: " << (options.get("g") ? "true" : "false") << endl;
- cout << endl << "leftover arguments: " << endl;
- for (vector<string>::const_iterator it = args.begin(); it != args.end(); ++it) {
- cout << "arg: " << *it << endl;
- }
+ cout << endl << "leftover arguments: " << endl;
+ for (vector<string>::const_iterator it = args.begin(); it != args.end(); ++it) {
+ cout << "arg: " << *it << endl;
+ }
- return 0;
+ return 0;
}
diff --git a/third-party/cram-0.7/cram/__init__.py b/third-party/cram-0.7/cram/__init__.py
new file mode 100644
index 0000000..4b626c4
--- /dev/null
+++ b/third-party/cram-0.7/cram/__init__.py
@@ -0,0 +1,6 @@
+"""Functional testing framework for command line applications"""
+
+from cram._main import main
+from cram._test import test, testfile
+
+__all__ = ['main', 'test', 'testfile']
diff --git a/third-party/cram-0.7/cram/__main__.py b/third-party/cram-0.7/cram/__main__.py
new file mode 100644
index 0000000..e6b0aef
--- /dev/null
+++ b/third-party/cram-0.7/cram/__main__.py
@@ -0,0 +1,10 @@
+"""Main module (invoked by "python -m cram")"""
+
+import sys
+
+import cram
+
+try:
+ sys.exit(cram.main(sys.argv[1:]))
+except KeyboardInterrupt:
+ pass
diff --git a/third-party/cram-0.7/cram/_cli.py b/third-party/cram-0.7/cram/_cli.py
new file mode 100644
index 0000000..8333b6b
--- /dev/null
+++ b/third-party/cram-0.7/cram/_cli.py
@@ -0,0 +1,134 @@
+"""The command line interface implementation"""
+
+import os
+import sys
+
+from cram._encoding import b, bytestype, stdoutb
+from cram._process import execute
+
+__all__ = ['runcli']
+
+def _prompt(question, answers, auto=None):
+ """Write a prompt to stdout and ask for answer in stdin.
+
+ answers should be a string, with each character a single
+ answer. An uppercase letter is considered the default answer.
+
+ If an invalid answer is given, this asks again until it gets a
+ valid one.
+
+ If auto is set, the question is answered automatically with the
+ specified value.
+ """
+ default = [c for c in answers if c.isupper()]
+ while True:
+ sys.stdout.write('%s [%s] ' % (question, answers))
+ sys.stdout.flush()
+ if auto is not None:
+ sys.stdout.write(auto + '\n')
+ sys.stdout.flush()
+ return auto
+
+ answer = sys.stdin.readline().strip().lower()
+ if not answer and default:
+ return default[0]
+ elif answer and answer in answers.lower():
+ return answer
+
+def _log(msg=None, verbosemsg=None, verbose=False):
+ """Write msg to standard out and flush.
+
+ If verbose is True, write verbosemsg instead.
+ """
+ if verbose:
+ msg = verbosemsg
+ if msg:
+ if isinstance(msg, bytestype):
+ stdoutb.write(msg)
+ else: # pragma: nocover
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+
+def _patch(cmd, diff):
+ """Run echo [lines from diff] | cmd -p0"""
+ out, retcode = execute([cmd, '-p0'], stdin=b('').join(diff))
+ return retcode == 0
+
+def runcli(tests, quiet=False, verbose=False, patchcmd=None, answer=None):
+ """Run tests with command line interface input/output.
+
+ tests should be a sequence of 2-tuples containing the following:
+
+ (test path, test function)
+
+ This function yields a new sequence where each test function is wrapped
+ with a function that handles CLI input/output.
+
+ If quiet is True, diffs aren't printed. If verbose is True,
+ filenames and status information are printed.
+
+ If patchcmd is set, a prompt is written to stdout asking if
+ changed output should be merged back into the original test. The
+ answer is read from stdin. If 'y', the test is patched using patch
+ based on the changed output.
+ """
+ total, skipped, failed = [0], [0], [0]
+
+ for path, test in tests:
+ def testwrapper():
+ """Test function that adds CLI output"""
+ total[0] += 1
+ _log(None, path + b(': '), verbose)
+
+ refout, postout, diff = test()
+ if refout is None:
+ skipped[0] += 1
+ _log('s', 'empty\n', verbose)
+ return refout, postout, diff
+
+ abspath = os.path.abspath(path)
+ errpath = abspath + b('.err')
+
+ if postout is None:
+ skipped[0] += 1
+ _log('s', 'skipped\n', verbose)
+ elif not diff:
+ _log('.', 'passed\n', verbose)
+ if os.path.exists(errpath):
+ os.remove(errpath)
+ else:
+ failed[0] += 1
+ _log('!', 'failed\n', verbose)
+ if not quiet:
+ _log('\n', None, verbose)
+
+ errfile = open(errpath, 'wb')
+ try:
+ for line in postout:
+ errfile.write(line)
+ finally:
+ errfile.close()
+
+ if not quiet:
+ origdiff = diff
+ diff = []
+ for line in origdiff:
+ stdoutb.write(line)
+ diff.append(line)
+
+ if (patchcmd and
+ _prompt('Accept this change?', 'yN', answer) == 'y'):
+ if _patch(patchcmd, diff):
+ _log(None, path + b(': merged output\n'), verbose)
+ os.remove(errpath)
+ else:
+ _log(path + b(': merge failed\n'))
+
+ return refout, postout, diff
+
+ yield (path, testwrapper)
+
+ if total[0] > 0:
+ _log('\n', None, verbose)
+ _log('# Ran %s tests, %s skipped, %s failed.\n'
+ % (total[0], skipped[0], failed[0]))
diff --git a/third-party/cram-0.7/cram/_diff.py b/third-party/cram-0.7/cram/_diff.py
new file mode 100644
index 0000000..4877305
--- /dev/null
+++ b/third-party/cram-0.7/cram/_diff.py
@@ -0,0 +1,158 @@
+"""Utilities for diffing test files and their output"""
+
+import codecs
+import difflib
+import re
+
+from cram._encoding import b
+
+__all__ = ['esc', 'glob', 'regex', 'unified_diff']
+
+def _regex(pattern, s):
+ """Match a regular expression or return False if invalid.
+
+ >>> from cram._encoding import b
+ >>> [bool(_regex(r, b('foobar'))) for r in (b('foo.*'), b('***'))]
+ [True, False]
+ """
+ try:
+ return re.match(pattern + b(r'\Z'), s)
+ except re.error:
+ return False
+
+def _glob(el, l):
+ r"""Match a glob-like pattern.
+
+ The only supported special characters are * and ?. Escaping is
+ supported.
+
+ >>> from cram._encoding import b
+ >>> bool(_glob(b(r'\* \\ \? fo?b*'), b('* \\ ? foobar')))
+ True
+ """
+ i, n = 0, len(el)
+ res = b('')
+ while i < n:
+ c = el[i:i + 1]
+ i += 1
+ if c == b('\\') and el[i] in b('*?\\'):
+ res += el[i - 1:i + 1]
+ i += 1
+ elif c == b('*'):
+ res += b('.*')
+ elif c == b('?'):
+ res += b('.')
+ else:
+ res += re.escape(c)
+ return _regex(res, l)
+
+def _matchannotation(keyword, matchfunc, el, l):
+ """Apply match function based on annotation keyword"""
+ ann = b(' (%s)\n' % keyword)
+ return el.endswith(ann) and matchfunc(el[:-len(ann)], l[:-1])
+
+def regex(el, l):
+ """Apply a regular expression match to a line annotated with '(re)'"""
+ return _matchannotation('re', _regex, el, l)
+
+def glob(el, l):
+ """Apply a glob match to a line annotated with '(glob)'"""
+ return _matchannotation('glob', _glob, el, l)
+
+def esc(el, l):
+ """Apply an escape match to a line annotated with '(esc)'"""
+ ann = b(' (esc)\n')
+
+ if el.endswith(ann):
+ el = codecs.escape_decode(el[:-len(ann)])[0] + b('\n')
+ if el == l:
+ return True
+
+ if l.endswith(ann):
+ l = codecs.escape_decode(l[:-len(ann)])[0] + b('\n')
+ return el == l
+
+class _SequenceMatcher(difflib.SequenceMatcher, object):
+ """Like difflib.SequenceMatcher, but supports custom match functions"""
+ def __init__(self, *args, **kwargs):
+ self._matchers = kwargs.pop('matchers', [])
+ super(_SequenceMatcher, self).__init__(*args, **kwargs)
+
+ def _match(self, el, l):
+ """Tests for matching lines using custom matchers"""
+ for matcher in self._matchers:
+ if matcher(el, l):
+ return True
+ return False
+
+ def find_longest_match(self, alo, ahi, blo, bhi):
+ """Find longest matching block in a[alo:ahi] and b[blo:bhi]"""
+ # SequenceMatcher uses find_longest_match() to slowly whittle down
+ # the differences between a and b until it has each matching block.
+ # Because of this, we can end up doing the same matches many times.
+ matches = []
+ for n, (el, line) in enumerate(zip(self.a[alo:ahi], self.b[blo:bhi])):
+ if el != line and self._match(el, line):
+ # This fools the superclass's method into thinking that the
+ # regex/glob in a is identical to b by replacing a's line (the
+ # expected output) with b's line (the actual output).
+ self.a[alo + n] = line
+ matches.append((n, el))
+ ret = super(_SequenceMatcher, self).find_longest_match(alo, ahi,
+ blo, bhi)
+ # Restore the lines replaced above. Otherwise, the diff output
+ # would seem to imply that the tests never had any regexes/globs.
+ for n, el in matches:
+ self.a[alo + n] = el
+ return ret
+
+def unified_diff(l1, l2, fromfile=b(''), tofile=b(''), fromfiledate=b(''),
+ tofiledate=b(''), n=3, lineterm=b('\n'), matchers=None):
+ r"""Compare two sequences of lines; generate the delta as a unified diff.
+
+ This is like difflib.unified_diff(), but allows custom matchers.
+
+ >>> from cram._encoding import b
+ >>> l1 = [b('a\n'), b('? (glob)\n')]
+ >>> l2 = [b('a\n'), b('b\n')]
+ >>> (list(unified_diff(l1, l2, b('f1'), b('f2'), b('1970-01-01'),
+ ... b('1970-01-02'))) ==
+ ... [b('--- f1\t1970-01-01\n'), b('+++ f2\t1970-01-02\n'),
+ ... b('@@ -1,2 +1,2 @@\n'), b(' a\n'), b('-? (glob)\n'), b('+b\n')])
+ True
+
+ >>> from cram._diff import glob
+ >>> list(unified_diff(l1, l2, matchers=[glob]))
+ []
+ """
+ if matchers is None:
+ matchers = []
+ started = False
+ matcher = _SequenceMatcher(None, l1, l2, matchers=matchers)
+ for group in matcher.get_grouped_opcodes(n):
+ if not started:
+ if fromfiledate:
+ fromdate = b('\t') + fromfiledate
+ else:
+ fromdate = b('')
+ if tofiledate:
+ todate = b('\t') + tofiledate
+ else:
+ todate = b('')
+ yield b('--- ') + fromfile + fromdate + lineterm
+ yield b('+++ ') + tofile + todate + lineterm
+ started = True
+ i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
+ yield (b("@@ -%d,%d +%d,%d @@" % (i1 + 1, i2 - i1, j1 + 1, j2 - j1)) +
+ lineterm)
+ for tag, i1, i2, j1, j2 in group:
+ if tag == 'equal':
+ for line in l1[i1:i2]:
+ yield b(' ') + line
+ continue
+ if tag == 'replace' or tag == 'delete':
+ for line in l1[i1:i2]:
+ yield b('-') + line
+ if tag == 'replace' or tag == 'insert':
+ for line in l2[j1:j2]:
+ yield b('+') + line
diff --git a/third-party/cram-0.7/cram/_encoding.py b/third-party/cram-0.7/cram/_encoding.py
new file mode 100644
index 0000000..d639cce
--- /dev/null
+++ b/third-party/cram-0.7/cram/_encoding.py
@@ -0,0 +1,106 @@
+"""Encoding utilities"""
+
+import os
+import sys
+
+try:
+ import builtins
+except ImportError:
+ import __builtin__ as builtins
+
+__all__ = ['b', 'bchr', 'bytestype', 'envencode', 'fsdecode', 'fsencode',
+ 'stdoutb', 'stderrb', 'u', 'ul', 'unicodetype']
+
+bytestype = getattr(builtins, 'bytes', str)
+unicodetype = getattr(builtins, 'unicode', str)
+
+if getattr(os, 'fsdecode', None) is not None:
+ fsdecode = os.fsdecode
+ fsencode = os.fsencode
+elif bytestype is not str:
+ if sys.platform == 'win32':
+ def fsdecode(s):
+ """Decode a filename from the filesystem encoding"""
+ if isinstance(s, unicodetype):
+ return s
+ encoding = sys.getfilesystemencoding()
+ if encoding == 'mbcs':
+ return s.decode(encoding)
+ else:
+ return s.decode(encoding, 'surrogateescape')
+
+ def fsencode(s):
+ """Encode a filename to the filesystem encoding"""
+ if isinstance(s, bytestype):
+ return s
+ encoding = sys.getfilesystemencoding()
+ if encoding == 'mbcs':
+ return s.encode(encoding)
+ else:
+ return s.encode(encoding, 'surrogateescape')
+ else:
+ def fsdecode(s):
+ """Decode a filename from the filesystem encoding"""
+ if isinstance(s, unicodetype):
+ return s
+ return s.decode(sys.getfilesystemencoding(), 'surrogateescape')
+
+ def fsencode(s):
+ """Encode a filename to the filesystem encoding"""
+ if isinstance(s, bytestype):
+ return s
+ return s.encode(sys.getfilesystemencoding(), 'surrogateescape')
+else:
+ def fsdecode(s):
+ """Decode a filename from the filesystem encoding"""
+ return s
+
+ def fsencode(s):
+ """Encode a filename to the filesystem encoding"""
+ return s
+
+if bytestype is str:
+ def envencode(s):
+ """Encode a byte string to the os.environ encoding"""
+ return s
+else:
+ envencode = fsdecode
+
+if getattr(sys.stdout, 'buffer', None) is not None:
+ stdoutb = sys.stdout.buffer
+ stderrb = sys.stderr.buffer
+else:
+ stdoutb = sys.stdout
+ stderrb = sys.stderr
+
+if bytestype is str:
+ def b(s):
+ """Convert an ASCII string literal into a bytes object"""
+ return s
+
+ bchr = chr
+
+ def u(s):
+ """Convert an ASCII string literal into a unicode object"""
+ return s.decode('ascii')
+else:
+ def b(s):
+ """Convert an ASCII string literal into a bytes object"""
+ return s.encode('ascii')
+
+ def bchr(i):
+ """Return a bytes character for a given integer value"""
+ return bytestype([i])
+
+ def u(s):
+ """Convert an ASCII string literal into a unicode object"""
+ return s
+
+try:
+ eval(r'u""')
+except SyntaxError:
+ ul = eval
+else:
+ def ul(e):
+ """Evaluate e as a unicode string literal"""
+ return eval('u' + e)
diff --git a/third-party/cram-0.7/cram/_main.py b/third-party/cram-0.7/cram/_main.py
new file mode 100644
index 0000000..11d457b
--- /dev/null
+++ b/third-party/cram-0.7/cram/_main.py
@@ -0,0 +1,211 @@
+"""Main entry point"""
+
+import optparse
+import os
+import shlex
+import shutil
+import sys
+import tempfile
+
+try:
+ import configparser
+except ImportError: # pragma: nocover
+ import ConfigParser as configparser
+
+from cram._cli import runcli
+from cram._encoding import b, fsencode, stderrb, stdoutb
+from cram._run import runtests
+from cram._xunit import runxunit
+
+def _which(cmd):
+ """Return the path to cmd or None if not found"""
+ cmd = fsencode(cmd)
+ for p in os.environ['PATH'].split(os.pathsep):
+ path = os.path.join(fsencode(p), cmd)
+ if os.path.isfile(path) and os.access(path, os.X_OK):
+ return os.path.abspath(path)
+ return None
+
+def _expandpath(path):
+ """Expands ~ and environment variables in path"""
+ return os.path.expanduser(os.path.expandvars(path))
+
+class _OptionParser(optparse.OptionParser):
+ """Like optparse.OptionParser, but supports setting values through
+ CRAM= and .cramrc."""
+
+ def __init__(self, *args, **kwargs):
+ self._config_opts = {}
+ optparse.OptionParser.__init__(self, *args, **kwargs)
+
+ def add_option(self, *args, **kwargs):
+ option = optparse.OptionParser.add_option(self, *args, **kwargs)
+ if option.dest and option.dest != 'version':
+ key = option.dest.replace('_', '-')
+ self._config_opts[key] = option.action == 'store_true'
+ return option
+
+ def parse_args(self, args=None, values=None):
+ config = configparser.RawConfigParser()
+ config.read(_expandpath(os.environ.get('CRAMRC', '.cramrc')))
+ defaults = {}
+ for key, isbool in self._config_opts.items():
+ try:
+ if isbool:
+ try:
+ value = config.getboolean('cram', key)
+ except ValueError:
+ value = config.get('cram', key)
+ self.error('--%s: invalid boolean value: %r'
+ % (key, value))
+ else:
+ value = config.get('cram', key)
+ except (configparser.NoSectionError, configparser.NoOptionError):
+ pass
+ else:
+ defaults[key] = value
+ self.set_defaults(**defaults)
+
+ eargs = os.environ.get('CRAM', '').strip()
+ if eargs:
+ args = args or []
+ args += shlex.split(eargs)
+
+ try:
+ return optparse.OptionParser.parse_args(self, args, values)
+ except optparse.OptionValueError:
+ self.error(str(sys.exc_info()[1]))
+
+def _parseopts(args):
+ """Parse command line arguments"""
+ p = _OptionParser(usage='cram [OPTIONS] TESTS...', prog='cram')
+ p.add_option('-V', '--version', action='store_true',
+ help='show version information and exit')
+ p.add_option('-q', '--quiet', action='store_true',
+ help="don't print diffs")
+ p.add_option('-v', '--verbose', action='store_true',
+ help='show filenames and test status')
+ p.add_option('-i', '--interactive', action='store_true',
+ help='interactively merge changed test output')
+ p.add_option('-d', '--debug', action='store_true',
+ help='write script output directly to the terminal')
+ p.add_option('-y', '--yes', action='store_true',
+ help='answer yes to all questions')
+ p.add_option('-n', '--no', action='store_true',
+ help='answer no to all questions')
+ p.add_option('-E', '--preserve-env', action='store_true',
+ help="don't reset common environment variables")
+ p.add_option('--keep-tmpdir', action='store_true',
+ help='keep temporary directories')
+ p.add_option('--shell', action='store', default='/bin/sh', metavar='PATH',
+ help='shell to use for running tests (default: %default)')
+ p.add_option('--shell-opts', action='store', metavar='OPTS',
+ help='arguments to invoke shell with')
+ p.add_option('--indent', action='store', default=2, metavar='NUM',
+ type='int', help=('number of spaces to use for indentation '
+ '(default: %default)'))
+ p.add_option('--xunit-file', action='store', metavar='PATH',
+ help='path to write xUnit XML output')
+ opts, paths = p.parse_args(args)
+ paths = [fsencode(path) for path in paths]
+ return opts, paths, p.get_usage
+
+def main(args):
+ """Main entry point.
+
+ If you're thinking of using Cram in other Python code (e.g., unit tests),
+ consider using the test() or testfile() functions instead.
+
+ :param args: Script arguments (excluding script name)
+ :type args: str
+ :return: Exit code (non-zero on failure)
+ :rtype: int
+ """
+ opts, paths, getusage = _parseopts(args)
+ if opts.version:
+ sys.stdout.write("""Cram CLI testing framework (version 0.7)
+
+Copyright (C) 2010-2016 Brodie Rao <brodie at bitheap.org> and others
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+""")
+ return
+
+ conflicts = [('--yes', opts.yes, '--no', opts.no),
+ ('--quiet', opts.quiet, '--interactive', opts.interactive),
+ ('--debug', opts.debug, '--quiet', opts.quiet),
+ ('--debug', opts.debug, '--interactive', opts.interactive),
+ ('--debug', opts.debug, '--verbose', opts.verbose),
+ ('--debug', opts.debug, '--xunit-file', opts.xunit_file)]
+ for s1, o1, s2, o2 in conflicts:
+ if o1 and o2:
+ sys.stderr.write('options %s and %s are mutually exclusive\n'
+ % (s1, s2))
+ return 2
+
+ shellcmd = _which(opts.shell)
+ if not shellcmd:
+ stderrb.write(b('shell not found: ') + fsencode(opts.shell) + b('\n'))
+ return 2
+ shell = [shellcmd]
+ if opts.shell_opts:
+ shell += shlex.split(opts.shell_opts)
+
+ patchcmd = None
+ if opts.interactive:
+ patchcmd = _which('patch')
+ if not patchcmd:
+ sys.stderr.write('patch(1) required for -i\n')
+ return 2
+
+ if not paths:
+ sys.stdout.write(getusage())
+ return 2
+
+ badpaths = [path for path in paths if not os.path.exists(path)]
+ if badpaths:
+ stderrb.write(b('no such file: ') + badpaths[0] + b('\n'))
+ return 2
+
+ if opts.yes:
+ answer = 'y'
+ elif opts.no:
+ answer = 'n'
+ else:
+ answer = None
+
+ tmpdir = os.environ['CRAMTMP'] = tempfile.mkdtemp('', 'cramtests-')
+ tmpdirb = fsencode(tmpdir)
+ proctmp = os.path.join(tmpdir, 'tmp')
+ for s in ('TMPDIR', 'TEMP', 'TMP'):
+ os.environ[s] = proctmp
+
+ os.mkdir(proctmp)
+ try:
+ tests = runtests(paths, tmpdirb, shell, indent=opts.indent,
+ cleanenv=not opts.preserve_env, debug=opts.debug)
+ if not opts.debug:
+ tests = runcli(tests, quiet=opts.quiet, verbose=opts.verbose,
+ patchcmd=patchcmd, answer=answer)
+ if opts.xunit_file is not None:
+ tests = runxunit(tests, opts.xunit_file)
+
+ hastests = False
+ failed = False
+ for path, test in tests:
+ hastests = True
+ refout, postout, diff = test()
+ if diff:
+ failed = True
+
+ if not hastests:
+ sys.stderr.write('no tests found\n')
+ return 2
+
+ return int(failed)
+ finally:
+ if opts.keep_tmpdir:
+ stdoutb.write(b('# Kept temporary directory: ') + tmpdirb +
+ b('\n'))
+ else:
+ shutil.rmtree(tmpdir)
diff --git a/third-party/cram-0.7/cram/_process.py b/third-party/cram-0.7/cram/_process.py
new file mode 100644
index 0000000..decdfbc
--- /dev/null
+++ b/third-party/cram-0.7/cram/_process.py
@@ -0,0 +1,54 @@
+"""Utilities for running subprocesses"""
+
+import os
+import signal
+import subprocess
+import sys
+
+from cram._encoding import fsdecode
+
+__all__ = ['PIPE', 'STDOUT', 'execute']
+
+PIPE = subprocess.PIPE
+STDOUT = subprocess.STDOUT
+
+def _makeresetsigpipe():
+ """Make a function to reset SIGPIPE to SIG_DFL (for use in subprocesses).
+
+ Doing subprocess.Popen(..., preexec_fn=makeresetsigpipe()) will prevent
+ Python's SIGPIPE handler (SIG_IGN) from being inherited by the
+ child process.
+ """
+ if (sys.platform == 'win32' or
+ getattr(signal, 'SIGPIPE', None) is None): # pragma: nocover
+ return None
+ return lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+def execute(args, stdin=None, stdout=None, stderr=None, cwd=None, env=None):
+ """Run a process and return its output and return code.
+
+ stdin may either be None or a string to send to the process.
+
+ stdout may either be None or PIPE. If set to PIPE, the process's output
+ is returned as a string.
+
+ stderr may either be None or STDOUT. If stdout is set to PIPE and stderr
+ is set to STDOUT, the process's stderr output will be interleaved with
+ stdout and returned as a string.
+
+ cwd sets the process's current working directory.
+
+ env can be set to a dictionary to override the process's environment
+ variables.
+
+ This function returns a 2-tuple of (output, returncode).
+ """
+ if sys.platform == 'win32': # pragma: nocover
+ args = [fsdecode(arg) for arg in args]
+
+ p = subprocess.Popen(args, stdin=PIPE, stdout=stdout, stderr=stderr,
+ cwd=cwd, env=env, bufsize=-1,
+ preexec_fn=_makeresetsigpipe(),
+ close_fds=os.name == 'posix')
+ out, err = p.communicate(stdin)
+ return out, p.returncode
diff --git a/third-party/cram-0.7/cram/_run.py b/third-party/cram-0.7/cram/_run.py
new file mode 100644
index 0000000..9111c0f
--- /dev/null
+++ b/third-party/cram-0.7/cram/_run.py
@@ -0,0 +1,77 @@
+"""The test runner"""
+
+import os
+import sys
+
+from cram._encoding import b, fsdecode, fsencode
+from cram._test import testfile
+
+__all__ = ['runtests']
+
+if sys.platform == 'win32': # pragma: nocover
+ def _walk(top):
+ top = fsdecode(top)
+ for root, dirs, files in os.walk(top):
+ yield (fsencode(root),
+ [fsencode(p) for p in dirs],
+ [fsencode(p) for p in files])
+else:
+ _walk = os.walk
+
+def _findtests(paths):
+ """Yield tests in paths in sorted order"""
+ for p in paths:
+ if os.path.isdir(p):
+ for root, dirs, files in _walk(p):
+ if os.path.basename(root).startswith(b('.')):
+ continue
+ for f in sorted(files):
+ if not f.startswith(b('.')) and f.endswith(b('.t')):
+ yield os.path.normpath(os.path.join(root, f))
+ else:
+ yield os.path.normpath(p)
+
+def runtests(paths, tmpdir, shell, indent=2, cleanenv=True, debug=False):
+ """Run tests and yield results.
+
+ This yields a sequence of 2-tuples containing the following:
+
+ (test path, test function)
+
+ The test function, when called, runs the test in a temporary directory
+ and returns a 3-tuple:
+
+ (list of lines in the test, same list with actual output, diff)
+ """
+ cwd = os.getcwd()
+ seen = set()
+ basenames = set()
+ for i, path in enumerate(_findtests(paths)):
+ abspath = os.path.abspath(path)
+ if abspath in seen:
+ continue
+ seen.add(abspath)
+
+ if not os.stat(path).st_size:
+ yield (path, lambda: (None, None, None))
+ continue
+
+ basename = os.path.basename(path)
+ if basename in basenames:
+ basename = basename + b('-%s' % i)
+ else:
+ basenames.add(basename)
+
+ def test():
+ """Run test file"""
+ testdir = os.path.join(tmpdir, basename)
+ os.mkdir(testdir)
+ try:
+ os.chdir(testdir)
+ return testfile(abspath, shell, indent=indent,
+ cleanenv=cleanenv, debug=debug,
+ testname=path)
+ finally:
+ os.chdir(cwd)
+
+ yield (path, test)
diff --git a/third-party/cram-0.7/cram/_test.py b/third-party/cram-0.7/cram/_test.py
new file mode 100644
index 0000000..27ef99c
--- /dev/null
+++ b/third-party/cram-0.7/cram/_test.py
@@ -0,0 +1,230 @@
+"""Utilities for running individual tests"""
+
+import itertools
+import os
+import re
+import time
+
+from cram._encoding import b, bchr, bytestype, envencode, unicodetype
+from cram._diff import esc, glob, regex, unified_diff
+from cram._process import PIPE, STDOUT, execute
+
+__all__ = ['test', 'testfile']
+
+_needescape = re.compile(b(r'[\x00-\x09\x0b-\x1f\x7f-\xff]')).search
+_escapesub = re.compile(b(r'[\x00-\x09\x0b-\x1f\\\x7f-\xff]')).sub
+_escapemap = dict((bchr(i), b(r'\x%02x' % i)) for i in range(256))
+_escapemap.update({b('\\'): b('\\\\'), b('\r'): b(r'\r'), b('\t'): b(r'\t')})
+
+def _escape(s):
+ """Like the string-escape codec, but doesn't escape quotes"""
+ return (_escapesub(lambda m: _escapemap[m.group(0)], s[:-1]) +
+ b(' (esc)\n'))
+
+def test(lines, shell='/bin/sh', indent=2, testname=None, env=None,
+ cleanenv=True, debug=False):
+ r"""Run test lines and return input, output, and diff.
+
+ This returns a 3-tuple containing the following:
+
+ (list of lines in test, same list with actual output, diff)
+
+ diff is a generator that yields the diff between the two lists.
+
+ If a test exits with return code 80, the actual output is set to
+ None and diff is set to [].
+
+ Note that the TESTSHELL environment variable is available in the
+ test (set to the specified shell). However, the TESTDIR and
+ TESTFILE environment variables are not available. To run actual
+ test files, see testfile().
+
+ Example usage:
+
+ >>> from cram._encoding import b
+ >>> refout, postout, diff = test([b(' $ echo hi\n'),
+ ... b(' [a-z]{2} (re)\n')])
+ >>> refout == [b(' $ echo hi\n'), b(' [a-z]{2} (re)\n')]
+ True
+ >>> postout == [b(' $ echo hi\n'), b(' hi\n')]
+ True
+ >>> bool(diff)
+ False
+
+ lines may also be a single bytes string:
+
+ >>> refout, postout, diff = test(b(' $ echo hi\n bye\n'))
+ >>> refout == [b(' $ echo hi\n'), b(' bye\n')]
+ True
+ >>> postout == [b(' $ echo hi\n'), b(' hi\n')]
+ True
+ >>> bool(diff)
+ True
+ >>> (b('').join(diff) ==
+ ... b('--- \n+++ \n@@ -1,2 +1,2 @@\n $ echo hi\n- bye\n+ hi\n'))
+ True
+
+ Note that the b() function is internal to Cram. If you're using Python 2,
+ use normal string literals instead. If you're using Python 3, use bytes
+ literals.
+
+ :param lines: Test input
+ :type lines: bytes or collections.Iterable[bytes]
+ :param shell: Shell to run test in
+ :type shell: bytes or str or list[bytes] or list[str]
+ :param indent: Amount of indentation to use for shell commands
+ :type indent: int
+ :param testname: Optional test file name (used in diff output)
+ :type testname: bytes or None
+ :param env: Optional environment variables for the test shell
+ :type env: dict or None
+ :param cleanenv: Whether or not to sanitize the environment
+ :type cleanenv: bool
+ :param debug: Whether or not to run in debug mode (don't capture stdout)
+ :type debug: bool
+ :return: Input, output, and diff iterables
+ :rtype: (list[bytes], list[bytes], collections.Iterable[bytes])
+ """
+ indent = b(' ') * indent
+ cmdline = indent + b('$ ')
+ conline = indent + b('> ')
+ usalt = 'CRAM%s' % time.time()
+ salt = b(usalt)
+
+ if env is None:
+ env = os.environ.copy()
+
+ if cleanenv:
+ for s in ('LANG', 'LC_ALL', 'LANGUAGE'):
+ env[s] = 'C'
+ env['TZ'] = 'GMT'
+ env['CDPATH'] = ''
+ env['COLUMNS'] = '80'
+ env['GREP_OPTIONS'] = ''
+
+ if isinstance(lines, bytestype):
+ lines = lines.splitlines(True)
+
+ if isinstance(shell, (bytestype, unicodetype)):
+ shell = [shell]
+ env['TESTSHELL'] = shell[0]
+
+ if debug:
+ stdin = []
+ for line in lines:
+ if not line.endswith(b('\n')):
+ line += b('\n')
+ if line.startswith(cmdline):
+ stdin.append(line[len(cmdline):])
+ elif line.startswith(conline):
+ stdin.append(line[len(conline):])
+
+ execute(shell + ['-'], stdin=b('').join(stdin), env=env)
+ return ([], [], [])
+
+ after = {}
+ refout, postout = [], []
+ i = pos = prepos = -1
+ stdin = []
+ for i, line in enumerate(lines):
+ if not line.endswith(b('\n')):
+ line += b('\n')
+ refout.append(line)
+ if line.startswith(cmdline):
+ after.setdefault(pos, []).append(line)
+ prepos = pos
+ pos = i
+ stdin.append(b('echo %s %s $?\n' % (usalt, i)))
+ stdin.append(line[len(cmdline):])
+ elif line.startswith(conline):
+ after.setdefault(prepos, []).append(line)
+ stdin.append(line[len(conline):])
+ elif not line.startswith(indent):
+ after.setdefault(pos, []).append(line)
+ stdin.append(b('echo %s %s $?\n' % (usalt, i + 1)))
+
+ output, retcode = execute(shell + ['-'], stdin=b('').join(stdin),
+ stdout=PIPE, stderr=STDOUT, env=env)
+ if retcode == 80:
+ return (refout, None, [])
+
+ pos = -1
+ ret = 0
+ for i, line in enumerate(output[:-1].splitlines(True)):
+ out, cmd = line, None
+ if salt in line:
+ out, cmd = line.split(salt, 1)
+
+ if out:
+ if not out.endswith(b('\n')):
+ out += b(' (no-eol)\n')
+
+ if _needescape(out):
+ out = _escape(out)
+ postout.append(indent + out)
+
+ if cmd:
+ ret = int(cmd.split()[1])
+ if ret != 0:
+ postout.append(indent + b('[%s]\n' % (ret)))
+ postout += after.pop(pos, [])
+ pos = int(cmd.split()[0])
+
+ postout += after.pop(pos, [])
+
+ if testname:
+ diffpath = testname
+ errpath = diffpath + b('.err')
+ else:
+ diffpath = errpath = b('')
+ diff = unified_diff(refout, postout, diffpath, errpath,
+ matchers=[esc, glob, regex])
+ for firstline in diff:
+ return refout, postout, itertools.chain([firstline], diff)
+ return refout, postout, []
+
+def testfile(path, shell='/bin/sh', indent=2, env=None, cleanenv=True,
+ debug=False, testname=None):
+ """Run test at path and return input, output, and diff.
+
+ This returns a 3-tuple containing the following:
+
+ (list of lines in test, same list with actual output, diff)
+
+ diff is a generator that yields the diff between the two lists.
+
+ If a test exits with return code 80, the actual output is set to
+ None and diff is set to [].
+
+ Note that the TESTDIR, TESTFILE, and TESTSHELL environment
+ variables are available to use in the test.
+
+ :param path: Path to test file
+ :type path: bytes or str
+ :param shell: Shell to run test in
+ :type shell: bytes or str or list[bytes] or list[str]
+ :param indent: Amount of indentation to use for shell commands
+ :type indent: int
+ :param env: Optional environment variables for the test shell
+ :type env: dict or None
+ :param cleanenv: Whether or not to sanitize the environment
+ :type cleanenv: bool
+ :param debug: Whether or not to run in debug mode (don't capture stdout)
+ :type debug: bool
+ :param testname: Optional test file name (used in diff output)
+ :type testname: bytes or None
+ :return: Input, output, and diff iterables
+ :rtype: (list[bytes], list[bytes], collections.Iterable[bytes])
+ """
+ f = open(path, 'rb')
+ try:
+ abspath = os.path.abspath(path)
+ env = env or os.environ.copy()
+ env['TESTDIR'] = envencode(os.path.dirname(abspath))
+ env['TESTFILE'] = envencode(os.path.basename(abspath))
+ if testname is None: # pragma: nocover
+ testname = os.path.basename(abspath)
+ return test(f, shell, indent=indent, testname=testname, env=env,
+ cleanenv=cleanenv, debug=debug)
+ finally:
+ f.close()
diff --git a/third-party/cram-0.7/cram/_xunit.py b/third-party/cram-0.7/cram/_xunit.py
new file mode 100644
index 0000000..0b3cb49
--- /dev/null
+++ b/third-party/cram-0.7/cram/_xunit.py
@@ -0,0 +1,173 @@
+"""xUnit XML output"""
+
+import locale
+import os
+import re
+import socket
+import sys
+import time
+
+from cram._encoding import u, ul
+
+__all__ = ['runxunit']
+
+_widecdataregex = ul(r"'(?:[^\x09\x0a\x0d\x20-\ud7ff\ue000-\ufffd"
+ r"\U00010000-\U0010ffff]|]]>)'")
+_narrowcdataregex = ul(r"'(?:[^\x09\x0a\x0d\x20-\ud7ff\ue000-\ufffd]"
+ r"|]]>)'")
+_widequoteattrregex = ul(r"'[^\x20\x21\x23-\x25\x27-\x3b\x3d"
+ r"\x3f-\ud7ff\ue000-\ufffd"
+ r"\U00010000-\U0010ffff]'")
+_narrowquoteattrregex = ul(r"'[^\x20\x21\x23-\x25\x27-\x3b\x3d"
+ r"\x3f-\ud7ff\ue000-\ufffd]'")
+_replacementchar = ul(r"'\N{REPLACEMENT CHARACTER}'")
+
+if sys.maxunicode >= 0x10ffff: # pragma: nocover
+ _cdatasub = re.compile(_widecdataregex).sub
+ _quoteattrsub = re.compile(_widequoteattrregex).sub
+else: # pragma: nocover
+ _cdatasub = re.compile(_narrowcdataregex).sub
+ _quoteattrsub = re.compile(_narrowquoteattrregex).sub
+
+def _cdatareplace(m):
+ """Replace _cdatasub() regex match"""
+ if m.group(0) == u(']]>'):
+ return u(']]>]]><![CDATA[')
+ else:
+ return _replacementchar
+
+def _cdata(s):
+ r"""Escape a string as an XML CDATA block.
+
+ >>> from cram._encoding import ul
+ >>> (_cdata('1<\'2\'>&"3\x00]]>\t\r\n') ==
+ ... ul(r"'<![CDATA[1<\'2\'>&\"3\ufffd]]>]]><![CDATA[\t\r\n]]>'"))
+ True
+ """
+ return u('<![CDATA[%s]]>') % _cdatasub(_cdatareplace, s)
+
+def _quoteattrreplace(m):
+ """Replace _quoteattrsub() regex match"""
+ return {u('\t'): u(' '),
+ u('\n'): u('
'),
+ u('\r'): u('
'),
+ u('"'): u('"'),
+ u('&'): u('&'),
+ u('<'): u('<'),
+ u('>'): u('>')}.get(m.group(0), _replacementchar)
+
+def _quoteattr(s):
+ r"""Escape a string for use as an XML attribute value.
+
+ >>> from cram._encoding import ul
+ >>> (_quoteattr('1<\'2\'>&"3\x00]]>\t\r\n') ==
+ ... ul(r"'\"1<\'2\'>&"3\ufffd]]>
\"'"))
+ True
+ """
+ return u('"%s"') % _quoteattrsub(_quoteattrreplace, s)
+
+def _timestamp():
+ """Return the current time in ISO 8601 format"""
+ tm = time.localtime()
+ if tm.tm_isdst == 1: # pragma: nocover
+ tz = time.altzone
+ else: # pragma: nocover
+ tz = time.timezone
+
+ timestamp = time.strftime('%Y-%m-%dT%H:%M:%S', tm)
+ tzhours = int(-tz / 60 / 60)
+ tzmins = int(abs(tz) / 60 % 60)
+ timestamp += u('%+03d:%02d') % (tzhours, tzmins)
+ return timestamp
+
+def runxunit(tests, xmlpath):
+ """Run tests with xUnit XML output.
+
+ tests should be a sequence of 2-tuples containing the following:
+
+ (test path, test function)
+
+ This function yields a new sequence where each test function is wrapped
+ with a function that writes test results to an xUnit XML file.
+ """
+ suitestart = time.time()
+ timestamp = _timestamp()
+ hostname = socket.gethostname()
+ total, skipped, failed = [0], [0], [0]
+ testcases = []
+
+ for path, test in tests:
+ def testwrapper():
+ """Run test and collect XML output"""
+ total[0] += 1
+
+ start = time.time()
+ refout, postout, diff = test()
+ testtime = time.time() - start
+
+ classname = path.decode(locale.getpreferredencoding(), 'replace')
+ name = os.path.basename(classname)
+
+ if postout is None:
+ skipped[0] += 1
+ testcase = (u(' <testcase classname=%(classname)s\n'
+ ' name=%(name)s\n'
+ ' time="%(time).6f">\n'
+ ' <skipped/>\n'
+ ' </testcase>\n') %
+ {'classname': _quoteattr(classname),
+ 'name': _quoteattr(name),
+ 'time': testtime})
+ elif diff:
+ failed[0] += 1
+ diff = list(diff)
+ diffu = u('').join(l.decode(locale.getpreferredencoding(),
+ 'replace')
+ for l in diff)
+ testcase = (u(' <testcase classname=%(classname)s\n'
+ ' name=%(name)s\n'
+ ' time="%(time).6f">\n'
+ ' <failure>%(diff)s</failure>\n'
+ ' </testcase>\n') %
+ {'classname': _quoteattr(classname),
+ 'name': _quoteattr(name),
+ 'time': testtime,
+ 'diff': _cdata(diffu)})
+ else:
+ testcase = (u(' <testcase classname=%(classname)s\n'
+ ' name=%(name)s\n'
+ ' time="%(time).6f"/>\n') %
+ {'classname': _quoteattr(classname),
+ 'name': _quoteattr(name),
+ 'time': testtime})
+ testcases.append(testcase)
+
+ return refout, postout, diff
+
+ yield path, testwrapper
+
+ suitetime = time.time() - suitestart
+ header = (u('<?xml version="1.0" encoding="utf-8"?>\n'
+ '<testsuite name="cram"\n'
+ ' tests="%(total)d"\n'
+ ' failures="%(failed)d"\n'
+ ' skipped="%(skipped)d"\n'
+ ' timestamp=%(timestamp)s\n'
+ ' hostname=%(hostname)s\n'
+ ' time="%(time).6f">\n') %
+ {'total': total[0],
+ 'failed': failed[0],
+ 'skipped': skipped[0],
+ 'timestamp': _quoteattr(timestamp),
+ 'hostname': _quoteattr(hostname),
+ 'time': suitetime})
+ footer = u('</testsuite>\n')
+
+ xmlfile = open(xmlpath, 'wb')
+ try:
+ xmlfile.write(header.encode('utf-8'))
+ for testcase in testcases:
+ xmlfile.write(testcase.encode('utf-8'))
+ xmlfile.write(footer.encode('utf-8'))
+ finally:
+ xmlfile.close()
diff --git a/third-party/cram-0.7/scripts/cram b/third-party/cram-0.7/scripts/cram
new file mode 100755
index 0000000..33f118e
--- /dev/null
+++ b/third-party/cram-0.7/scripts/cram
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+import sys
+
+import cram
+
+try:
+ sys.exit(cram.main(sys.argv[1:]))
+except KeyboardInterrupt:
+ pass
diff --git a/tools/Darwin/clang-format b/tools/Darwin/clang-format
deleted file mode 100755
index 33201aa..0000000
Binary files a/tools/Darwin/clang-format and /dev/null differ
diff --git a/tools/Linux/clang-format b/tools/Linux/clang-format
deleted file mode 100755
index c450691..0000000
Binary files a/tools/Linux/clang-format and /dev/null differ
diff --git a/tools/check-formatting b/tools/check-formatting
deleted file mode 100755
index dccf458..0000000
--- a/tools/check-formatting
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-PLATFORM=$(uname)
-CLANGFORMAT="./tools/${PLATFORM}/clang-format -style=file"
-
-if [ "$1" == "--all" ]
-then
- find include src tests/unit \( -name *.cpp -or -name *.h \) -print0 \
- | xargs -n1 -0 ${CLANGFORMAT} -output-replacements-xml \
- | grep -c "<replacement " > /dev/null
- grepCode=$?
-elif [ "$1" == "--staged" ]
-then
- git diff --cached --name-only --diff-filter=ACMRT | grep -e '.*\.h' -e '.*\.cpp' \
- | xargs -n1 ${CLANGFORMAT} -output-replacements-xml \
- | grep -c "<replacement " >/dev/null
- grepCode=$?
-else
- echo "Please specify --all or --staged"
- exit 1
-fi
-
-# grep exits 0 => found needed formatting changes
-if [ $grepCode -ne 0 ]
-then
- echo "Formatting looks good!"
- exit 0
-else
- echo "****************************************************"
- echo "Code needs formatting! Please use 'tools/format-all'"
- echo "****************************************************"
- exit 1
-fi
diff --git a/tools/format-all b/tools/format-all
deleted file mode 100755
index 919f82f..0000000
--- a/tools/format-all
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# This command can be run by the user to clang-format everything.
-
-PLATFORM=$(uname)
-CLANGFORMAT="./tools/${PLATFORM}/clang-format -style=file"
-
-find include src tests/unit \( -name *.cpp -or -name *.h \) -print0 | xargs -n1 -0 ${CLANGFORMAT} -i
diff --git a/tools/git-clang-format b/tools/git-clang-format
deleted file mode 100755
index 0c45762..0000000
--- a/tools/git-clang-format
+++ /dev/null
@@ -1,485 +0,0 @@
-#!/usr/bin/env python
-#
-#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-r"""
-clang-format git integration
-============================
-
-This file provides a clang-format integration for git. Put it somewhere in your
-path and ensure that it is executable. Then, "git clang-format" will invoke
-clang-format on the changes in current files or a specific commit.
-
-For further details, run:
-git clang-format -h
-
-Requires Python 2.7
-"""
-
-import argparse
-import collections
-import contextlib
-import errno
-import os
-import re
-import subprocess
-import sys
-
-usage = 'git clang-format [OPTIONS] [<commit>] [--] [<file>...]'
-
-desc = '''
-Run clang-format on all lines that differ between the working directory
-and <commit>, which defaults to HEAD. Changes are only applied to the working
-directory.
-
-The following git-config settings set the default of the corresponding option:
- clangFormat.binary
- clangFormat.commit
- clangFormat.extension
- clangFormat.style
-'''
-
-# Name of the temporary index file in which save the output of clang-format.
-# This file is created within the .git directory.
-temp_index_basename = 'clang-format-index'
-
-
-Range = collections.namedtuple('Range', 'start, count')
-
-
-def main():
- config = load_git_config()
-
- # In order to keep '--' yet allow options after positionals, we need to
- # check for '--' ourselves. (Setting nargs='*' throws away the '--', while
- # nargs=argparse.REMAINDER disallows options after positionals.)
- argv = sys.argv[1:]
- try:
- idx = argv.index('--')
- except ValueError:
- dash_dash = []
- else:
- dash_dash = argv[idx:]
- argv = argv[:idx]
-
- default_extensions = ','.join([
- # From clang/lib/Frontend/FrontendOptions.cpp, all lower case
- 'c', 'h', # C
- 'm', # ObjC
- 'mm', # ObjC++
- 'cc', 'cp', 'cpp', 'c++', 'cxx', 'hpp', # C++
- # Other languages that clang-format supports
- 'proto', 'protodevel', # Protocol Buffers
- 'js', # JavaScript
- 'ts', # TypeScript
- ])
-
- p = argparse.ArgumentParser(
- usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
- description=desc)
- p.add_argument('--binary',
- default=config.get('clangformat.binary', 'clang-format'),
- help='path to clang-format'),
- p.add_argument('--commit',
- default=config.get('clangformat.commit', 'HEAD'),
- help='default commit to use if none is specified'),
- p.add_argument('--diff', action='store_true',
- help='print a diff instead of applying the changes')
- p.add_argument('--extensions',
- default=config.get('clangformat.extensions',
- default_extensions),
- help=('comma-separated list of file extensions to format, '
- 'excluding the period and case-insensitive')),
- p.add_argument('-f', '--force', action='store_true',
- help='allow changes to unstaged files')
- p.add_argument('-p', '--patch', action='store_true',
- help='select hunks interactively')
- p.add_argument('-q', '--quiet', action='count', default=0,
- help='print less information')
- p.add_argument('--style',
- default=config.get('clangformat.style', None),
- help='passed to clang-format'),
- p.add_argument('-v', '--verbose', action='count', default=0,
- help='print extra information')
- # We gather all the remaining positional arguments into 'args' since we need
- # to use some heuristics to determine whether or not <commit> was present.
- # However, to print pretty messages, we make use of metavar and help.
- p.add_argument('args', nargs='*', metavar='<commit>',
- help='revision from which to compute the diff')
- p.add_argument('ignored', nargs='*', metavar='<file>...',
- help='if specified, only consider differences in these files')
- opts = p.parse_args(argv)
-
- opts.verbose -= opts.quiet
- del opts.quiet
-
- commit, files = interpret_args(opts.args, dash_dash, opts.commit)
- changed_lines = compute_diff_and_extract_lines(commit, files)
- if opts.verbose >= 1:
- ignored_files = set(changed_lines)
- filter_by_extension(changed_lines, opts.extensions.lower().split(','))
- if opts.verbose >= 1:
- ignored_files.difference_update(changed_lines)
- if ignored_files:
- print 'Ignoring changes in the following files (wrong extension):'
- for filename in ignored_files:
- print ' ', filename
- if changed_lines:
- print 'Running clang-format on the following files:'
- for filename in changed_lines:
- print ' ', filename
- if not changed_lines:
- print 'no modified files to format'
- return
- # The computed diff outputs absolute paths, so we must cd before accessing
- # those files.
- cd_to_toplevel()
- old_tree = create_tree_from_workdir(changed_lines)
- new_tree = run_clang_format_and_save_to_tree(changed_lines,
- binary=opts.binary,
- style=opts.style)
- if opts.verbose >= 1:
- print 'old tree:', old_tree
- print 'new tree:', new_tree
- if old_tree == new_tree:
- if opts.verbose >= 0:
- print 'clang-format did not modify any files'
- elif opts.diff:
- print_diff(old_tree, new_tree)
- else:
- changed_files = apply_changes(old_tree, new_tree, force=opts.force,
- patch_mode=opts.patch)
- if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
- print 'changed files:'
- for filename in changed_files:
- print ' ', filename
-
-
-def load_git_config(non_string_options=None):
- """Return the git configuration as a dictionary.
-
- All options are assumed to be strings unless in `non_string_options`, in which
- is a dictionary mapping option name (in lower case) to either "--bool" or
- "--int"."""
- if non_string_options is None:
- non_string_options = {}
- out = {}
- for entry in run('git', 'config', '--list', '--null').split('\0'):
- if entry:
- name, value = entry.split('\n', 1)
- if name in non_string_options:
- value = run('git', 'config', non_string_options[name], name)
- out[name] = value
- return out
-
-
-def interpret_args(args, dash_dash, default_commit):
- """Interpret `args` as "[commit] [--] [files...]" and return (commit, files).
-
- It is assumed that "--" and everything that follows has been removed from
- args and placed in `dash_dash`.
-
- If "--" is present (i.e., `dash_dash` is non-empty), the argument to its
- left (if present) is taken as commit. Otherwise, the first argument is
- checked if it is a commit or a file. If commit is not given,
- `default_commit` is used."""
- if dash_dash:
- if len(args) == 0:
- commit = default_commit
- elif len(args) > 1:
- die('at most one commit allowed; %d given' % len(args))
- else:
- commit = args[0]
- object_type = get_object_type(commit)
- if object_type not in ('commit', 'tag'):
- if object_type is None:
- die("'%s' is not a commit" % commit)
- else:
- die("'%s' is a %s, but a commit was expected" % (commit, object_type))
- files = dash_dash[1:]
- elif args:
- if disambiguate_revision(args[0]):
- commit = args[0]
- files = args[1:]
- else:
- commit = default_commit
- files = args
- else:
- commit = default_commit
- files = []
- return commit, files
-
-
-def disambiguate_revision(value):
- """Returns True if `value` is a revision, False if it is a file, or dies."""
- # If `value` is ambiguous (neither a commit nor a file), the following
- # command will die with an appropriate error message.
- run('git', 'rev-parse', value, verbose=False)
- object_type = get_object_type(value)
- if object_type is None:
- return False
- if object_type in ('commit', 'tag'):
- return True
- die('`%s` is a %s, but a commit or filename was expected' %
- (value, object_type))
-
-
-def get_object_type(value):
- """Returns a string description of an object's type, or None if it is not
- a valid git object."""
- cmd = ['git', 'cat-file', '-t', value]
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- return None
- return stdout.strip()
-
-
-def compute_diff_and_extract_lines(commit, files):
- """Calls compute_diff() followed by extract_lines()."""
- diff_process = compute_diff(commit, files)
- changed_lines = extract_lines(diff_process.stdout)
- diff_process.stdout.close()
- diff_process.wait()
- if diff_process.returncode != 0:
- # Assume error was already printed to stderr.
- sys.exit(2)
- return changed_lines
-
-
-def compute_diff(commit, files):
- """Return a subprocess object producing the diff from `commit`.
-
- The return value's `stdin` file object will produce a patch with the
- differences between the working directory and `commit`, filtered on `files`
- (if non-empty). Zero context lines are used in the patch."""
- cmd = ['git', 'diff-index', '-p', '-U0', commit, '--']
- cmd.extend(files)
- p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
- p.stdin.close()
- return p
-
-
-def extract_lines(patch_file):
- """Extract the changed lines in `patch_file`.
-
- The return value is a dictionary mapping filename to a list of (start_line,
- line_count) pairs.
-
- The input must have been produced with ``-U0``, meaning unidiff format with
- zero lines of context. The return value is a dict mapping filename to a
- list of line `Range`s."""
- matches = {}
- for line in patch_file:
- match = re.search(r'^\+\+\+\ [^/]+/(.*)', line)
- if match:
- filename = match.group(1).rstrip('\r\n')
- match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
- if match:
- start_line = int(match.group(1))
- line_count = 1
- if match.group(3):
- line_count = int(match.group(3))
- if line_count > 0:
- matches.setdefault(filename, []).append(Range(start_line, line_count))
- return matches
-
-
-def filter_by_extension(dictionary, allowed_extensions):
- """Delete every key in `dictionary` that doesn't have an allowed extension.
-
- `allowed_extensions` must be a collection of lowercase file extensions,
- excluding the period."""
- allowed_extensions = frozenset(allowed_extensions)
- for filename in dictionary.keys():
- base_ext = filename.rsplit('.', 1)
- if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
- del dictionary[filename]
-
-
-def cd_to_toplevel():
- """Change to the top level of the git repository."""
- toplevel = run('git', 'rev-parse', '--show-toplevel')
- os.chdir(toplevel)
-
-
-def create_tree_from_workdir(filenames):
- """Create a new git tree with the given files from the working directory.
-
- Returns the object ID (SHA-1) of the created tree."""
- return create_tree(filenames, '--stdin')
-
-
-def run_clang_format_and_save_to_tree(changed_lines, binary='clang-format',
- style=None):
- """Run clang-format on each file and save the result to a git tree.
-
- Returns the object ID (SHA-1) of the created tree."""
- def index_info_generator():
- for filename, line_ranges in changed_lines.iteritems():
- mode = oct(os.stat(filename).st_mode)
- blob_id = clang_format_to_blob(filename, line_ranges, binary=binary,
- style=style)
- yield '%s %s\t%s' % (mode, blob_id, filename)
- return create_tree(index_info_generator(), '--index-info')
-
-
-def create_tree(input_lines, mode):
- """Create a tree object from the given input.
-
- If mode is '--stdin', it must be a list of filenames. If mode is
- '--index-info' is must be a list of values suitable for "git update-index
- --index-info", such as "<mode> <SP> <sha1> <TAB> <filename>". Any other mode
- is invalid."""
- assert mode in ('--stdin', '--index-info')
- cmd = ['git', 'update-index', '--add', '-z', mode]
- with temporary_index_file():
- p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
- for line in input_lines:
- p.stdin.write('%s\0' % line)
- p.stdin.close()
- if p.wait() != 0:
- die('`%s` failed' % ' '.join(cmd))
- tree_id = run('git', 'write-tree')
- return tree_id
-
-
-def clang_format_to_blob(filename, line_ranges, binary='clang-format',
- style=None):
- """Run clang-format on the given file and save the result to a git blob.
-
- Returns the object ID (SHA-1) of the created blob."""
- clang_format_cmd = [binary, filename]
- if style:
- clang_format_cmd.extend(['-style='+style])
- clang_format_cmd.extend([
- '-lines=%s:%s' % (start_line, start_line+line_count-1)
- for start_line, line_count in line_ranges])
- try:
- clang_format = subprocess.Popen(clang_format_cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE)
- except OSError as e:
- if e.errno == errno.ENOENT:
- die('cannot find executable "%s"' % binary)
- else:
- raise
- clang_format.stdin.close()
- hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
- hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout,
- stdout=subprocess.PIPE)
- clang_format.stdout.close()
- stdout = hash_object.communicate()[0]
- if hash_object.returncode != 0:
- die('`%s` failed' % ' '.join(hash_object_cmd))
- if clang_format.wait() != 0:
- die('`%s` failed' % ' '.join(clang_format_cmd))
- return stdout.rstrip('\r\n')
-
-
- at contextlib.contextmanager
-def temporary_index_file(tree=None):
- """Context manager for setting GIT_INDEX_FILE to a temporary file and deleting
- the file afterward."""
- index_path = create_temporary_index(tree)
- old_index_path = os.environ.get('GIT_INDEX_FILE')
- os.environ['GIT_INDEX_FILE'] = index_path
- try:
- yield
- finally:
- if old_index_path is None:
- del os.environ['GIT_INDEX_FILE']
- else:
- os.environ['GIT_INDEX_FILE'] = old_index_path
- os.remove(index_path)
-
-
-def create_temporary_index(tree=None):
- """Create a temporary index file and return the created file's path.
-
- If `tree` is not None, use that as the tree to read in. Otherwise, an
- empty index is created."""
- gitdir = run('git', 'rev-parse', '--git-dir')
- path = os.path.join(gitdir, temp_index_basename)
- if tree is None:
- tree = '--empty'
- run('git', 'read-tree', '--index-output='+path, tree)
- return path
-
-
-def print_diff(old_tree, new_tree):
- """Print the diff between the two trees to stdout."""
- # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
- # is expected to be viewed by the user, and only the former does nice things
- # like color and pagination.
- subprocess.check_call(['git', 'diff', old_tree, new_tree, '--'])
-
-
-def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
- """Apply the changes in `new_tree` to the working directory.
-
- Bails if there are local changes in those files and not `force`. If
- `patch_mode`, runs `git checkout --patch` to select hunks interactively."""
- changed_files = run('git', 'diff-tree', '-r', '-z', '--name-only', old_tree,
- new_tree).rstrip('\0').split('\0')
- if not force:
- unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
- if unstaged_files:
- print >>sys.stderr, ('The following files would be modified but '
- 'have unstaged changes:')
- print >>sys.stderr, unstaged_files
- print >>sys.stderr, 'Please commit, stage, or stash them first.'
- sys.exit(2)
- if patch_mode:
- # In patch mode, we could just as well create an index from the new tree
- # and checkout from that, but then the user will be presented with a
- # message saying "Discard ... from worktree". Instead, we use the old
- # tree as the index and checkout from new_tree, which gives the slightly
- # better message, "Apply ... to index and worktree". This is not quite
- # right, since it won't be applied to the user's index, but oh well.
- with temporary_index_file(old_tree):
- subprocess.check_call(['git', 'checkout', '--patch', new_tree])
- index_tree = old_tree
- else:
- with temporary_index_file(new_tree):
- run('git', 'checkout-index', '-a', '-f')
- return changed_files
-
-
-def run(*args, **kwargs):
- stdin = kwargs.pop('stdin', '')
- verbose = kwargs.pop('verbose', True)
- strip = kwargs.pop('strip', True)
- for name in kwargs:
- raise TypeError("run() got an unexpected keyword argument '%s'" % name)
- p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- stdin=subprocess.PIPE)
- stdout, stderr = p.communicate(input=stdin)
- if p.returncode == 0:
- if stderr:
- if verbose:
- print >>sys.stderr, '`%s` printed to stderr:' % ' '.join(args)
- print >>sys.stderr, stderr.rstrip()
- if strip:
- stdout = stdout.rstrip('\r\n')
- return stdout
- if verbose:
- print >>sys.stderr, '`%s` returned %s' % (' '.join(args), p.returncode)
- if stderr:
- print >>sys.stderr, stderr.rstrip()
- sys.exit(2)
-
-
-def die(message):
- print >>sys.stderr, 'error:', message
- sys.exit(2)
-
-
-if __name__ == '__main__':
- main()
diff --git a/tools/win32/clang-format.exe b/tools/win32/clang-format.exe
deleted file mode 100644
index d42fb80..0000000
Binary files a/tools/win32/clang-format.exe and /dev/null differ
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/unanimity.git
More information about the debian-med-commit
mailing list