last-pair-probs
===============

This script reads alignments of paired DNA reads to a genome, and:

1. estimates the distribution of distances between paired reads,
2. estimates the probability that each alignment represents the
   genomic source of the read.

The script takes as input two files of alignments, where one read from
each pair is in one file, and the other read is in the other file.

Typical usage::

  lastdb -m1111110 humandb human/chr*.fa
  lastal -Q1 -e120 -i1 humandb reads1.fastq > temp1.maf
  lastal -Q1 -e120 -i1 humandb reads2.fastq > temp2.maf
  last-pair-probs.py temp1.maf temp2.maf > results.maf

If your reads come from potentially-spliced RNA molecules, use the -r
option::

  last-pair-probs.py -r temp1.maf temp2.maf > results.maf

Without -r, it assumes the distances between paired reads follow a
normal distribution.  With -r, it assumes the distances follow a
skewed (log-normal) distribution, which is much more appropriate for
spliced RNA.

Details
-------

* The script writes the alignments with "mismap" probabilities,
  i.e. the probability that the alignment does not represent the
  genomic source of the read.  By default, it discards alignments with
  mismap probability > 0.01.

* It assumes that each pair of reads comes from opposite strands of a
  DNA molecule.  The "distance" between them means the distance
  between their 5' ends.  Positive distance indicates tail-to-tail
  orientation (with the 5' end being the head and the 3' end being the
  tail).  Negative distance indicates head-to-head orientation.
  Negative distances are not considered when -r is used, nor for
  circular chromosomes.

* The script reads one batch of alignments at a time from each file
  (by looking for lines starting with "# batch").  It assumes that
  each pair of batches has the alignments for one pair of reads.  To
  achieve that, the read pairs should be in the same order in the
  fastq files, and the lastal -i1 option ensures there is one query
  per batch.

* The input files may be in either format produced by lastal (maf or
  tabular).  They must include header lines (of the kind produced by
  lastal) describing the alignment parameters.

* By default, the script makes two passes over each file.  So they
  must be real files (not pipes).  However, if you use option -e, or
  both -f and -s, it makes just one pass over each file.

* If a read name ends in neither "/1" nor "/2", the script appends
  "/1" if it comes from the first file or "/2" if it comes from the
  second.

Options
-------

  -h, --help
         Print a help message and exit.

  -r, --rna
         Specifies that the fragments are from potentially-spliced RNA.

  -e, --estdist
         Just estimate the distribution of distances.

  -m M, --mismap=M
         Don't write alignments with mismap probability > M.

  -f BP, --fraglen=BP
         The mean distance in bp.  (With -r, the mean of
         ln[distance].)  If this is not specified, the script will
         estimate it from the alignments.

  -s BP, --sdev=BP
         The standard deviation of distance in bp.  (With -r, the
         standard deviation of ln[distance].)  If this is not
         specified, the script will estimate it from the alignments.

  -d PROB, --disjoint=PROB
         The prior probability that a pair of reads comes from
         disjoint locations (e.g., different chromosomes).  This may
         arise from real differences between the genome and the source
         of the reads, or from errors in obtaining the reads or the
         genome sequence.

  -c CHROM, --circular=CHROM
         Specifies that the chromosome named CHROM is circular.  You
         can use this option more than once (e.g., -c chrM -c chrP).
         As a special case, "." means all chromosomes are circular.
         If this option is not used, "chrM" is assumed to be circular
         (but if it is used, only the specified CHROMs are assumed to
         be circular.)

Tips
----

* For greater speed and convenience, first estimate the distance
  distribution from a sample of your data (using -e), then analyze all
  your data with this estimate (using -f and -s).

* You can avoid temp files by using named pipes::

    mkfifo pipe1 pipe2
    lastal -Q1 -e120 -i1 humandb reads1.fastq > pipe1 &
    lastal -Q1 -e120 -i1 humandb reads2.fastq > pipe2 &
    last-pair-probs.py -f250 -s30 pipe1 pipe2 > results.maf

  This streams the alignments from lastal to last-pair-probs.

* To go faster, try a fast version of Python such as PyPy.

* To go really fast, try gapless alignment (add -j1 to the lastal
  options).  Often, this is only minusculely less accurate than gapped
  alignment.

* Tabular output (lastal option -f0) is smaller and faster.

Using multiple CPUs
-------------------

With large datasets, it's important to go faster by using multiple
CPUs.  One way to do that is by using GNU parallel
(http://www.gnu.org/software/parallel/), as follows.

* Split reads1.fastq into multiple files, with (say) 100000 reads per
  file::

    split -l400000 -a5 reads1.fastq 1

  This assumes that a new fastq record begins every 4th line, i.e. no
  line wrapping.  The created files will be called 1aaaaa, 1aaaab,
  etc.

* Split reads2.fastq::

    split -l400000 -a5 reads2.fastq 2

* Make a file called (say) last-pair.sh, with the following content
  (or similar - you might want to use -r, -j1, etc)::

    #! /bin/sh
    lastal -Q1 -e120 -i1 "$3" "$4" > /tmp/$$.1
    lastal -Q1 -e120 -i1 "$3" "$5" > /tmp/$$.2
    last-pair-probs.py -f "$1" -s "$2" /tmp/$$.1 /tmp/$$.2
    rm /tmp/$$.*

* Set execute permission::

    chmod +x last-pair.sh

* Run it in parallel on all your CPU cores::

    parallel --xapply ./last-pair.sh 250 30 humandb ::: 1* ::: 2* > results.maf

  Here we have specified a mean distance of 250 and a standard
  deviation of 30.

Reference
---------

For more information, please see this article:

  An approximate Bayesian approach for mapping paired-end DNA reads to
  a reference genome.  Shrestha AM, Frith MC.  Bioinformatics 2013
  29(8):965-972.
