\documentclass[letterpaper,11pt]{article}

\usepackage{latexsym,delcher}

\PortraitPage
\def\baselinestretch{1.0}
\def\thepage{{\footnotesize\arabic{page}}}
\def\today{22~October 2007}

\def\Pgm#1{\texttt{#1}}
\def\correctfrags{\Pgm{correct-frags}}
\def\correctolaps{\Pgm{correct-olaps}}
\def\ofs{\Pgm{olap-from-seeds}}
\def\overlap{\Pgm{overlap}}
\def\overmerry{\Pgm{overmerry}}
\newenvironment{technotes}{\bq\small\bf\bi\exdent{Technical Notes:}}{\ei\eq}
\def\btn{\begin{technotes}}
\def\etn{\end{technotes}}


\begin{document}

\pagestyle{PlainWithDate}
\thispagestyle{EmptyWithDate}
\RaggedRight

\bc\Large
  \ofs \smallskip\\
  Overview \& Technical Notes

  \bigskip
  \normalsize Arthur~L. Delcher\footnote{adelcher@umd.edu}
\ec

\section{Introduction}

Program \ofs\ computes overlaps between reads and determines
corrections to those reads in a single step.  It replaces the
previous programs \overlap\ and \correctfrags\ in the Celera
Assembler pipeline.

There are two principal differences between the overlap function
of \ofs\ and \overlap:
\bn
\item
  \ofs\ reads the anchor positions (seeds) of all possible overlaps
  from an overlap store, as opposed to computing them itself
  using exact-match kmers stored in a hash table.  This allows
  anchor positions to be determined using longer or variable-length
  kmers, or based on frequency of occurrence of kmers in the
  entire dataset.  In the current pipeline, these anchor positions
  are computed by the \overmerry\ program.
\item
  \ofs\ incorporates new routines to compute alignments involving
  reads likely to contain homopolymer run-length errors, such as
  454 reads.
  \btn
  \item
    There currently are two different versions of the homopoly
    align routines.  One is modeled after the Landau-Vishkin
    procedure used in \overlap.  This runs quickly but can produce
    non-optimal alignment because of the scoring scheme for
    homopoly alignments.  The second is a simpler, banded alignment
    in a traditional alignment matrix.  This gets optimal alignments
    for any scoring scheme but runs more slowly.
  \etn
\en
In most other respects, the overlap function is the same between
the two programs.  From a given seed position, an alignment
extension is attempted in each direction.  Alignments that
extend to the end of a read in both directions and that meet the
percent identity threshold are output as overlaps.
\btn
\item
  In \ofs, the alignment is first computed
  from the anchor position toward the left in order to determine the
  starting position of the overlap.  Then the entire overlap alignment
  is computed from that position toward the right.  Note that this
  recomputes the portion of the alignment between the left end and
  the anchor position.  The reason to do this is to make all alignments
  consistent for indels with respect to the reference read (\eg, all
  homopolymer indels occur at the right of the alignment).  This
  produces better multi-alignments over the reference read for
  error correction.

  In \overlap, the alignment is computed in two separate extensions
  in the two directions, and then these extensions are combined into
  a single alignment.
\etn

The error-correction function in \ofs\ is similar to the one in
\correctfrags.  The principal difference is that it constructs
a true multi-alignment of all overlapping reads with respect to the
reference read and uses this to determine corrections.  There is
also a special correction for 454-type reads to make the length of
homopolymer runs equal to the average length of the run in all reads
(including the reference) in the multi-alignment.

Error correction in \correctfrags\ was based on simple counts
of how often each base was confirmed or differed from the
corresponding bases of overlapping reads.  These counts did
not track correlated differences in the overlapping reads, nor
could they insert more than a single base at any single position
in the reference read.

The error correction in \ofs\ assumes that seeds for \EMPH{ALL}
reads that might overlap a given read are available when the
program is run.  The same assumption was made by \correctfrags.


\section{Running \ofs}

Input to \ofs\ is a set of seed positions together with the
read sequences to which the seeds refer.  The reads must be present
in a gatekeeper store (created by the \Pgm{gatekeeper} program).
The seeds typically are generated by \overmerry and then loaded into
an overlap store from which \ofs\ retrieves them, although there also is
an option to read the seeds from a text file.

Output is a set of overlaps and also, if desired, a set of
corrections to be applied to the given set of reads.  Both types
of output are the same format as produced by the earlier
\overlap\ and \correctfrags\ programs.

Program usage is:
\bq
  \ofs \, \emph{options} \, \emph{gkpStore} \, \emph{lo-iid} \, \emph{hi-iid}
\eq
\emph{lo-iid} and \emph{hi-iid} specify the range of reference reads
to which overlaps are to be computed.  More specifically, all seeds
involving any read in this range will be processed to see if they
extend to a valid overlap.

Program options are these:
\bi
\exdent
  \Pgm{-a} \quad
  Output ``asymmetric'' overlaps, \ie, only overlaps where the reference
  read iid~$<$~the other read's iid.  This is not the default behaviour,
  which is to output all overlaps to each reference read.  Thus, without
  \Pgm{-a}, if \emph{lo-iid} and \emph{hi-iid} specify all reads, every
  overlap will be output twice:  once as $(a,b)$ and once as $(b,a)$.
  \btn
  \item
    \Pgm{-a} is generally the desired behaviour since program \Pgm{overlapStore},
    when it reads overlap $(a,b)$, will enter both overlaps $(a,b)$ and
    $(b,a)$ into the overlap store.
  \item
    Perhaps this should be the default behaviour with an option for the
    other behaviour?
  \item
    Note that when generating error corrections, all possible overlaps are
    calculated and used to create corrections even though they may not
    be output because of this option.
  \etn

\exdent
  \Pgm{-b} \quad
   Output binary overlap messages.  Without this option, overlaps are
   output in a text format.
   \btn
   \item
     The format of the text output is one overlap per line, with the following
     fields:
     \emph{aiid \, biid \, dir \, alo \, ahi \, alen \, bstart \, bend \, blen \, error}
     where \emph{dir} is the orientation of the $b$ read (\Pgm{f} forward or
     \Pgm{r} reverse); \emph{alo} and \emph{ahi} specify the portion of the
     $a$ read involved in the overlap; \emph{alen} is the length of the $a$
     read; \emph{bstart} and \emph{bend} specify the portion of the
     $b$ read involved in the overlap; \emph{blen} is the length of the $b$
     read; and \emph{error} is the percent error of the alignment in the overlap
     region.

     The $a$ read is always assumed to be in the forward orientation.  \emph{dir}
     indicates the orientation of the $b$ read.  All coordinates are space-based
     (\eg, the first 5 bases of a read have $\mbox{\emph{lo}} = 0$ and
     $\mbox{\emph{hi}} = 5$) and with respect to the clear range of the read.
   \etn

\exdent
  \Pgm{-c} \emph{fn} \quad
  Output corrections to file \emph{fn}.

\exdent
  \Pgm{-d} $n$ \quad
  Used to set keep flag in correction record on end of frags with less
  than $n$ olaps.
  \btn
  \item
    Leftover from \correctfrags\ and
    not currently implemented.  \correctfrags\ used to keep track of the
    number of overlaps on each end of a read and used this flag to mark
    reads with low overlaps on either end.  \correctolaps\ read it and
    output the corrected overlap if the flag was on, regardless of the
    quality of the overlap.  \ofs\ currently does not keep track of
    overlap degrees and always sets the keep flag
    so that \correctolaps\ will output all overlaps.
  \etn

\exdent
  \Pgm{-e} \quad
  Extend fragments beyond $3'$ clear range.
  \btn
  \item
    Leftover from \correctfrags.
    Causes the $3'$ trimming of the reference reads to be ignored when
    computing overlaps.  Was intended to implement a form of
    overlap-based trimming.  It used to check how far a read was
    confirmed by overlaps past it $3'$ trim point and output the
    length of that extension as a correction message.  It no longer
    does this in the currect \ofs.
  \etn

\exdent
  \Pgm{-F} \emph{fn} \quad
  Read seeds from text file \emph{fn}.  The format of seeds is
  one seed per line, each line containing:
  \emph{aiid \, biid \, $[\mbox{\tt f}|\mbox{\tt r}]$ \, apos \, bpos \, ct}
  Any additional entries on the line are ignored.
  Entries are not reversed, \ie, the $(a,b)$ seed does \EMPH{NOT}
  automatically generate the $(b,a)$ seed, too.  The positions are relative
  to the clear range of the read.  If the $b$ read is reversed, the $b$ position
  is with respect to the reversed sequence.
  \btn
  \item
    \emph{ct} is the frequency of the mer that generated the seed.  The value
    has no effect in \ofs, but is passed along as part of the overlap message
    that results from the seed.
  \etn

\exdent
  \Pgm{-G} \quad
  Do partial overlaps, \ie, local alignments that need not extend to the end
  of reads.
  \btn
  \item
    Implemented for both standard and homopoly-type reads, but not thoroughly
    tested for the homopoly type.
  \etn

\exdent
  \Pgm{-h} \quad
  Print the usage message.

\exdent
  \Pgm{-o} \emph{fn} \quad
  Send overlaps to file or store \emph{fn}.

\exdent
  \Pgm{-S} \emph{fn} \quad
  Read seeds from binary overlap store \emph{fn}.

\exdent
  \Pgm{-t} $n$ \quad
  Use $n$ p-threads.  \textbf{Not currently implemented.}

\exdent
  \Pgm{-v} $n$ \quad
  Set verbose level to $n$; higher values give more debugging output.

\exdent
  \Pgm{-y} $x$ \quad
  Allow max error rate of $x$ in alignments (\eg, $0.03$ for $3\%$ error).
  The value cannot exceed the constant \verb`AS_GUIDE_ERROR_RATE`, which
  is also the default value.
  \btn
  \item
    The meaning of this value for homopolymer-run errors is problematic.
    Because these errors are significantly more common than errors in
    conventional reads a different scale seems appropriate.  \ofs\ currently
    uses alignment penalties of:
    \bi
    \item
      $1$ for homopolymer run-length errors, \ie, indels of the same letter
      as the preceding letter;
    \item
      $3$ for other indels; and
    \item
      $5$ for mismatches.
    \ei
    For homopoly alignments the error rate is converted to an equivalent
    penalty score which is used to determine if the alignment succeeds.
    The current conversion has the score equal to $4$ times the number
    of errors allowed by the error rate.  The value $4$ is the
    constant \verb`HOMOPOLY_SCORE_MULTIPLIER` in \Pgm{SharedOVL.h}.
    Because of this conversion, the error rate output in overlap messages
    can be larger than the specified error rate.
  \etn

\exdent
  \Pgm{-z} \quad
  Do \EMPH{NOT} try to correct read errors.  No corrections will be output.
\ei

The following options are leftover from \correctfrags\ and were
used to determine the parameters for the correction scheme.  Because a
different correction scheme based on the multi-alignment is now used,
these options no longer have any effect.
\bi
\exdent
  \Pgm{-k} $n$ \quad
  Prevent correction in a region covered by an exact match of $n$ bases.

\exdent
  \Pgm{-p} \quad
  Don't use haplotype counts to correct.  Without this option, if
  a position looks like at least 2 haplotypes, it is not allowed
  to be corrected.

\exdent
  \Pgm{-V} $n$ \quad
  Require $n$ exact match bases around an error (combined count
  on both sides) to vote to change a base.

\exdent
  \Pgm{-x} $n$ \quad
  Don't prevent correction on first and last $n$ bases of exact match
  regions (whose length is set by \Pgm{-k} option).
\ei

\section{Algorithms}

\subsection{Program Flow}

\ofs\ was developed by modifying the
\correctfrags code, so it shares the general program flow of
that program as well as much of the code.  The principal conceptual
change was just to replace the part of \correctfrags\ that
read overlaps by new code to read seeds and determine if they
extend to true overlaps.

The main program steps are these:
\bn
\item
  Parameters processed and data structures allocated and initialized.
\item
  The block of reference (or $a$) reads (\ie, reads specified by iid's
  on command line) is read from the gatekeeper store and stored in an
  array.
\item
  Seeds corresponding to the $a$ reads are extracted from the
  seed store and sorted into ascending order by $b$ read iid.
\item
  Eash seed is processed in order.
  \bn
  \item
    If the seed has a new $b$ read, the $b$ read is gotten from the
    gatekeeper store.  Note that the $b$ reads are read sequentially
    from the gatekeeper store, except for skipping over reads that
    don't occur in any of the seeds.
  \item
    An alignment extension is attempted from the anchor position of the
    seed to the left (toward the $5'$ end of the $a$ read).  If it
    succeeds (\ie, reaches the end of one of the reads for conventional
    overlaps, or automatically succeeds for partial overlaps), an
    alignment extension is attempted from that point to the right.
    This revisits the first left alignment, but has the advantage of
    constructing all alignments in the same directions relative to the
    $a$ read so that homopoly indels can easily be positioned on the
    same side (the right) of the homopoly run.  If this alignment succeeds,
    and is sufficiently long and within the error bound, the difference
    positions in the alignment are saved in an array associated with the
    $a$ read.
  \en
  \btn
  \item
    Overlaps cannot be output when the seeds are processed because the
    correlated difference check may eliminate them.  That check cannot
    be done until all overlaps for the $a$ read have been collected
    and converted to a multi-alignment.
  \item
    Computing these alignments is the most time-consuming step of the
    program and should be multi-threaded.  It can be done (fairly
    easily, I think) in the same way as in \correctfrags:
    \bi
    \item
      $b$ reads are read in a block at a time, corresponding to a block
      of seeds.
    \item
      Each thread runs down the same block of seeds, but only processes
      seeds whose $a$ read iid $\cong$ the thread id (mod number of threads).
      This distributes the workload fairly evenly and prevents threads
      colliding on the global data structures associated with the $a$ reads.
      The most significant change to the current program to implement
      this scheme is to the step to store the overlap differences
      with each $a$ read.  This currently uses \Pgm{realloc} to
      grow the space to store these.  I don't think that will work
      multi-threaded, so some other batching or preallocation strategy
      will need to be used to store these differences.
    \item
      The differences currently don't store the corresponding quality values.
      Because there are relatively few differences (as a fraction of
      the total sequence length), it would not take much space to store
      this information and it could be used in the correction step.
    \ei
  \etn
\item
  After all seeds are processed, each of the reference reads is processed in
  order.  For each read $a$, all its overlap differences are used to construct
  a multi-alignment over it.  If correlated differences are being checked, overlaps
  that fail the check are eliminated.  The remaining reads in the overlap are
  used to correct bases in $a$.  The current correction is done independently
  in each column.  A position in $a$ is corrected if there are sufficiently few
  $b$ reads in the corresponding column that match the existing $a$ value and
  there are sufficiently many reads that have an alternative value.

  An additional correction step is done if the $a$ read is a homopoly-type read.
  In this case, each homopolymer-run region in $a$ has its length adjusted to
  the average of the lengths of the corresponding runs in the columns above
  this region (the average is weighted to favour non-homopoly runs in the
  above region if there are any).  The average includes the length of the $a$
  region itself, so if the same set of reads is present when the other reads
  are processed as the $a$ read, they all should get the same homopoly run
  length.

  At this point corrections and overlaps are output for read $a$.
  \btn
  \item
    This is not multi-threaded yet.  It can be done so in any number of ways,
    since only information stored with read $a$ is being used/modified.
  \item
    The multi-alignments currently are just the agglomeration of the
    pairwise alignments to the reference read $a$.  Nothing is done to
    make insertions internally consistent.  \Eg, the following currently
    occurs:
    \bq
      \begin{tabular}{rl}
        $b_1$ & \ldots \verb`atcgatcgcta` \ldots \\
        $b_2$ & \ldots \verb`atctc--gcta` \ldots \\
        $b_3$ & \ldots \verb`atcgatcgcta` \ldots \\
        $b_4$ & \ldots \verb`atctc--gcta` \ldots \\
          $a$ & \ldots \verb`atc----gcta` \ldots
      \end{tabular}
    \eq
    when it should be:
    \bq
      \begin{tabular}{rl}
        $b_1$ & \ldots \verb`atcgatcgcta` \ldots \\
        $b_2$ & \ldots \verb`atc--tcgcta` \ldots \\
        $b_3$ & \ldots \verb`atcgatcgcta` \ldots \\
        $b_4$ & \ldots \verb`atc--tcgcta` \ldots \\
          $a$ & \ldots \verb`atc----gcta` \ldots
      \end{tabular}
    \eq
    The problem occurs most frequently in homopoly reads where:
    \bq
      \begin{tabular}{rl}
        $b_1$ & \ldots \verb`attctt--g` \ldots \\
        $b_2$ & \ldots \verb`atttctttg` \ldots \\
        $b_3$ & \ldots \verb`attcttt-g` \ldots \\
        $b_4$ & \ldots \verb`attttcttg` \ldots \\
          $a$ & \ldots \verb`atttttt-g` \ldots
      \end{tabular}
    \eq
    should be:
    \bq
      \begin{tabular}{rl}
        $b_1$ & \ldots \verb`att--ctt-g` \ldots \\
        $b_2$ & \ldots \verb`attt-ctttg` \ldots \\
        $b_3$ & \ldots \verb`att--ctttg` \ldots \\
        $b_4$ & \ldots \verb`attttctt-g` \ldots \\
          $a$ & \ldots \verb`attt--tttg` \ldots
      \end{tabular}
    \eq
  \item
    Quality values are not used yet.  They probably should be.
  \item
    Code exists to display the multi-alignments.  The routine is
    \verb`Display_Multialignment` and is automatically executed
    if the verbose level (set by the \verb`-v` option) is greater
    than zero.
  \item
    There are lots of extra debugging outputs in the code, as well as
    comments here changes could/should be made.  They are indicated
    by \verb`//**ALD` comments.
  \etn

\en

\subsection{Homopolymer Alignments}

There currently are three functions to compute homopolymer-type alignments.
They are
\verb`Fwd_Homopoly_Prefix_Match`,
\verb`Fwd_Banded_Homopoly_Prefix_Match` and
\verb`Rev_Homopoly_Match_Start`.  All are in \Pgm{SharedOVL.c}.

\subsubsection{\Pgm{Fwd\_Homopoly\_Prefix\_Match}}

This routine mimics the Landau-Vishkin (L-V) algorithm to compute alignments.
Because alignments are computed from an anchor point, the alignments can
be viewed as matching the prefixes of the strings that begin at the
anchor point.  The general idea of the L-V algorithm is to compute the
longest prefix of string $a$ that matches a prefix of string $b$ with
at most $e$ errors where the alignment ends on diagonal $d$ ($d$ is the difference
in lengths of the aligned prefixes).  The computation can be mapped to a
pyramidal matrix, shown in Figure~\ref{LVpyramidfig}, where the rows represent
the number of errors $e$ and the columns represent the diagonals $d$, and
the value in each cell is the length of the prefix of string $a$ that
meets the conditions for the cell.

\begin{figure}

\unitlength=0.25pt
\newcounter{pct}
\bc
\begin{picture}(1400,500)
  \setcounter{pct}{-1}
  \multiput(100,350)(0,-100){3}{\addtocounter{pct}{1}\makebox(0,0)[c]{$e=\mbox{\arabic{pct}}$}}
  \multiput(100,65)(0,-15){3}{\makebox(0,0)[c]{.}}
  \multiput(280,70)(-30,-15){3}{\makebox(0,0)[c]{.}}
  \multiput(800,65)(0,-15){3}{\makebox(0,0)[c]{.}}
  \multiput(1320,65)(30,-15){3}{\makebox(0,0)[c]{.}}
%
  \setcounter{pct}{-3}
  \multiput(400,500)(200,0){5}{\addtocounter{pct}{1}\makebox(0,0)[c]{$d=\mbox{\arabic{pct}}$}}
%
  \put(300,100){\line(0,1){100}}
  \put(500,100){\line(0,1){200}}
  \put(700,100){\line(0,1){300}}
  \put(900,100){\line(0,1){300}}
  \put(1100,100){\line(0,1){200}}
  \put(1300,100){\line(0,1){100}}
%
  \put(300,100){\line(1,0){1000}}
  \put(300,200){\line(1,0){1000}}
  \put(500,300){\line(1,0){600}}
  \put(700,400){\line(1,0){200}}
\end{picture}
\ec

\caption{Pyramidal matrix used in Landau-Vishkin prefix alignment.}
  \label{LVpyramidfig}
\end{figure}

The initial value in cell $c[e=0,d=0]$ is just the length of the longest
exact-match prefix shared by strings $a$ and $b$.  In general, the value
in cell $c[e,d]$ can be computed from the three cells above it, $c[e-1,d-1]$,
$c[e-1,d]$ and $c[e-1,d+1]$, by the following steps:
\bn
\item
  Let $m = \max \left\{\begin{array}{ll}
    c[e-1,d-1] & \mbox{missing character in $a$}\\
    1 + c[e-1,d] & \mbox{mismatch} \\
    1 + c[e-1,d+1] & \mbox{missing character in $b$}
  \end{array} \right.$
\item
  Set $c[e,d]$ to $m +$ the length of the longest exact match starting
  at character $m+1$ in $a$ and character $m+1+d$ in $b$.
\en
This algorithm is effective because it pursues long exact matches
and quickly finds alignments with relatively few errors, which are
typically present in overlapping reads, while filling in very few
cell entries.

In function \verb`Fwd_Homopoly_Prefix_Match`, the routine was modified
to also keep the value of an error score at each cell, where the
error values were:  $1$ for a homopoly run indel, $3$ for an initial indel,
$5$ for a mismatch.  Instead of maximizing the match length at each cell,
the routine minimized the error score.  This is only an heuristic, however,
since error scores do not correlate precisely with the number of errors (the matrix
rows).  As a result, non-optimal alignments can be produced and in the current
version of the code, this routine is not used.

It should be possible, however,
to modify it either by using error scores as the rows, or by
doing (relatively rarely) a more complicated calculation at each cell.

\subsubsection{\Pgm{Fwd\_Banded\_Homopoly\_Prefix\_Match}}

This routine computes values in a standard alignment matrix using the above $(1,3,5)$
error scores.  Only a limited number of entries are computed on each row
of the matrix (this is the ``band'') based on their scores relative to the best
score on the row.  This routine is substantially slower than the
Landau-Vishkin routine, but it gets the best-scoring alignment (within
the banding constraints).  It is the routine currently used to
compute homopolymer-type alignments.

\subsubsection{\Pgm{Rev\_Homopoly\_Match\_Start}}

This routine is used compute homopolymer-type alignments in
the ``reverse'' direction (\ie, to the left) from the initial
anchor point.  It's only purpose is to find the anchor point
for the start of the full alignment that will be computed in
the forward direction, and so it does not backtrack through the
matrix to generate the actual alignment---it merely returns
the alignment endpoint.

It uses a modified L-V algorithm
that detects when the simple L-V algorithm could produce a
non-optimal value and does an additional check on the number
of mismatches on the diagonal to choose the most promising value
for the cell.  This is still a heuristic, but in tests so far has
been producing accurate alignments positions.

\btn
\item
  The L-V algorithm also allows banding.  Hopelessly bad (or very
  likely bad) cells can be pruned as each row of the pyramid
  is generated.  Then only cells beneath the surviving band
  are calculated on the next row.  This is done in the current
  code, but can be improved further.
\etn


\section{Code Organization}

Program files are in the \Pgm{AS\_OVL} directory of the Celera
Assembler.  All are checked in to the \verb`wgs-assembler` code
repository at SourceForge.

\bi
\exdent
  \Pgm{OlapFromSeedsOVL.c} is the main program module
\exdent
  \Pgm{OlapFromSeedsOVL.h} contains constants, type definitions,
  function prototypes and global variable declarations.
\exdent
  \Pgm{SharedOVL.c} contains the basic alignment routines.
\exdent
  \Pgm{SharedOVL.h} contains declarations for \Pgm{SharedOVL.c}.
\exdent
  \Pgm{olap-seeds-doc.tex} is this document.
\ei


\section{Tests}

The module was tested using 454 reads, ABI reads, and combinations of
the two on shotgun sequences for the Moore bacterium M025 and for
\emph{Cryptosporidum muris}.  Based on the quality of unitigs
produced by the assembler, the new module yielded comparable results
to the previous overlapper using just 454 reads, and significantly
better results on 454 reads and combined 454/ABI read sets.  Testing
is still ongoing to adjust parameters and modify assembly steps (\eg,
eliminate duplicate 454 reads) to optimize the overall quality of
assemblies.


\section{Open Issues}

\bn
\item
  Multiple threads are not yet implemented.
\item
  The quality of homopoly-type overlaps is not accurately measured
  by a simple error percentage.  It may be appropriate to use a
  different value for such overlaps in the output error messages.
  This is not as big an issue after error correction as it is before
  error correction.
\item
  Some simple code exists for discriminating overlaps based on
  correlated differences.  The current routine is only implemented for
  non-homopoly reads and is not thoroughly tested.  It checks for
  two columns in the multi-alignment where $\ge 3$ reads have one
  letter (or gap) and $\ge 3$ other reads have a different letter.
  (The value $3$ is an easy to change parameter.)  The reads that differ
  from the reference sequence in both columns are eliminated from
  overlaps and from being used in corrections.
  \btn
  \item
    Since reads are eliminated, the multi-alignment can change (\eg,
    it can have columns eliminated).  Thus the multi-alignment needs
    to be repaired or rebuild.  That's not implemented yet.
  \item
    For homopoly reads, columns that represent homopoly run-length
    variations should not be used in this step.
  \etn
\item
  Partial overlaps are implemented for homopoly reads, but not
  thoroughly tested for them.
  \btn
  \item
    One issue is the scoring function for homopoly alignments, which
    is used to determine the end of the partial overlap.  The error
    penalties are well-defined, but it's not so clear what the positive
    match score should be to implement a given error rate.
  \etn
\item
  Quality values are not currently used.  Since multi-alignments are built
  by keeping just the differences between $b$ reads and the reference
  $a$ read, the overhead of storing these values would be small and
  they could help error correction.
\item
  Try the heuristic used in \Pgm{Rev\_Homopoly\_Match\_Start} in
  \Pgm{Fwd\_Homopoly\_Prefix\_Match} to see if it produces satisfactory
  alignments significantly faster than the banded alignment routine.
\item
  Error correction currently treats all homopoly run-length variation
  as the same.  \Eg, if half of the reads have run lengths of about $10$,
  while the other half have run lengths of about $2$, they all will be
  average together to make run lengths of $6$.  This is bad.  There should
  be some kind of clustering of run lengths, and distinct differences
  should be eliminated as overlaps.
\item
  Don't-know characters (\ie, N's) are not handled in the current code.
  They will mismatch any A,C.G,T but match each other.
\item
  There are some leftover references to ``shredded reads'' in the code.
  They are handle differently, \eg, no attempts are made to correct them.
  I don't think they are used anymore---perhaps the flag to identify
  them no longer exists?
\en

\end{document}
