Full Code of arq5x/poretools for AI

master e426b1f09e86 cached
162 files
2.3 MB
621.4k tokens
119 symbols
1 requests
Download .txt
Showing preview only (2,481K chars total). Download the full file or copy to clipboard to get everything.
Repository: arq5x/poretools
Branch: master
Commit: e426b1f09e86
Files: 162
Total size: 2.3 MB

Directory structure:
gitextract_uu4w_ikh/

├── .gitignore
├── Dockerfile
├── LICENSE
├── MANIFEST.in
├── README.md
├── appveyor/
│   ├── install.ps1
│   └── run_with_env.cmd
├── appveyor.yml
├── docs/
│   ├── Makefile
│   ├── conf.py
│   ├── content/
│   │   ├── examples.rst
│   │   ├── help.rst
│   │   ├── history.rst
│   │   ├── installation.rst
│   │   └── notebook.rst
│   ├── index.rst
│   └── requirements.txt
├── poretools/
│   ├── Event.py
│   ├── Fast5File.py
│   ├── __init__.py
│   ├── combine.py
│   ├── events.py
│   ├── fasta.py
│   ├── fastq.py
│   ├── formats.py
│   ├── hist.py
│   ├── index.py
│   ├── ipynb/
│   │   └── test_run_report.ipynb
│   ├── metadata.py
│   ├── nucdist.py
│   ├── occupancy.py
│   ├── organise.py
│   ├── poretools_main.py
│   ├── qual_v_pos.py
│   ├── qualdist.py
│   ├── readstats.py
│   ├── scripts/
│   │   ├── __init__.py
│   │   ├── poretools
│   │   ├── poretools-script.py
│   │   └── poretools.bat
│   ├── squiggle.py
│   ├── statistics.py
│   ├── stats.py
│   ├── tabular.py
│   ├── times.py
│   ├── version.py
│   ├── winner.py
│   └── yield_plot.py
├── requirements.txt
├── setup.py
└── test_data/
    ├── 2016_3_4_3507_1_ch120_read240_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read353_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read415_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read418_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read433_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read443_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read505_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read521_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read542_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read586_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read635_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read706_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read83_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read89_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1066_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1079_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1169_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1250_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1377_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1387_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read160_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read217_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read223_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read249_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read324_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read326_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read382_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read42_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read501_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read562_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read601_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read618_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read700_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read743_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read831_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read833_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read843_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read857_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read899_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read914_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read940_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read969_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read204_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read270_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read361_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read365_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read376_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read384_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read404_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read422_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read430_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read503_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read521_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read635_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read647_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read723_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read753_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read763_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read783_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read790_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read95_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1130_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1132_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1150_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1404_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1414_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1456_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1474_strand.fast5
    ├── COLLES_L160693_20160728_FNFAB23794_MN17350_sequencing_run_E_coli_K12_1D_R9_SpotON_41280_ch52_read58_strand.fast5
    ├── YYYYMMDD_HHMM_SampleID/
    │   ├── Fail/
    │   │   ├── 0/
    │   │   │   ├── 2016_3_4_3507_1_ch120_read240_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read353_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read415_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read418_strand.fast5
    │   │   │   └── 2016_3_4_3507_1_ch120_read433_strand.fast5
    │   │   ├── 1/
    │   │   │   ├── 2016_3_4_3507_1_ch120_read443_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read505_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read521_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read542_strand.fast5
    │   │   │   └── 2016_3_4_3507_1_ch120_read586_strand.fast5
    │   │   └── 2/
    │   │       ├── 2016_3_4_3507_1_ch120_read635_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read706_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read83_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read89_strand.fast5
    │   │       └── 2016_3_4_3507_1_ch126_read1066_strand.fast5
    │   └── Pass/
    │       ├── 0/
    │       │   ├── 2016_3_4_3507_1_ch126_read1079_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1169_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1250_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1377_strand.fast5
    │       │   └── 2016_3_4_3507_1_ch126_read1387_strand.fast5
    │       ├── 1/
    │       │   ├── 2016_3_4_3507_1_ch126_read160_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read217_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read223_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read249_strand.fast5
    │       │   └── 2016_3_4_3507_1_ch126_read324_strand.fast5
    │       └── 2/
    │           ├── 2016_3_4_3507_1_ch126_read326_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read382_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read42_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read501_strand.fast5
    │           └── 2016_3_4_3507_1_ch126_read562_strand.fast5
    ├── exp_2D_fail.fa
    ├── exp_2D_fail.fq
    ├── exp_all_nucdist
    ├── exp_all_qualdist
    ├── exp_all_stats
    ├── exp_all_winner
    ├── exp_fail_nucdist
    ├── exp_fail_qualdist
    ├── exp_pass_stats
    ├── exp_pass_winner
    ├── exp_total.fa
    ├── exp_total.fq
    └── poretools-tests.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.pyc
build/
dist/
*.egg-info


================================================
FILE: Dockerfile
================================================
###############################################
# Dockerfile to build poretools container image
# Based on Ubuntu 14.04
# Build with:
#   sudo docker build -t poretools .
###############################################

# Use ubuntu 14.04 base image
FROM ubuntu:14.04

# set non-interactive mode
ENV DEBIAN_FRONTEND noninteractive

############# BEGIN INSTALLATION ##############

# Prepare to install R
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
RUN echo 'deb http://cran.rstudio.com/bin/linux/ubuntu trusty/' >> /etc/apt/sources.list
RUN apt-get update

# Install dependencies
RUN apt-get -y install git python-tables python-setuptools python-pip python-dev cython libhdf5-serial-dev r-base python-rpy2

# Upgrade numexpr
RUN pip install numexpr --upgrade

# Install R packages
RUN Rscript -e 'options("repos" = c(CRAN = "http://cran.rstudio.com/")); install.packages("codetools"); install.packages("MASS"); install.packages("ggplot2")'

# Install poretools
RUN git clone https://github.com/arq5x/poretools /tmp/poretools
RUN cd /tmp/poretools && python setup.py install

############## INSTALLATION END ##############

# Set entrypoint so container can be used as executable
ENTRYPOINT ["poretools"]

# File author/maintainer info
MAINTAINER Stephen Turner <lastname at virginia dot edu>


================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright © 2013,2014,2015,206,2017 Nicholas Loman, Aaron Quinlan

Permission is hereby granted, free of charge, to any person obtaining a copy of this 
software and associated documentation files (the “Software”), to deal in the Software without 
restriction, including without limitation the rights to use, copy, modify, merge, publish, 
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or 
substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: MANIFEST.in
================================================
include requirements.txt

================================================
FILE: README.md
================================================
### poretools: a toolkit for working with nanopore sequencing data from Oxford Nanopore.

*Nick Loman and Aaron Quinlan*

Complete installation instructions and usage examples can be found on the [poretools documentation site](http://poretools.readthedocs.org).

Requirements
===================
- HDF5 >= 1.8.7 (http://www.hdfgroup.org/HDF5/)
- Python >= 2.7
- h5py >= 2.2
- matplotlib
- seaborn
- pandas

Contributors
============
@arq5x
@nickloman
@brentp


================================================
FILE: appveyor/install.ps1
================================================
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/

$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"

$PYTHON_PRERELEASE_REGEX = @"
(?x)
(?<major>\d+)
\.
(?<minor>\d+)
\.
(?<micro>\d+)
(?<prerelease>[a-z]{1,2}\d+)
"@


function Download ($filename, $url) {
    $webclient = New-Object System.Net.WebClient

    $basedir = $pwd.Path + "\"
    $filepath = $basedir + $filename
    if (Test-Path $filename) {
        Write-Host "Reusing" $filepath
        return $filepath
    }

    # Download and retry up to 3 times in case of network transient errors.
    Write-Host "Downloading" $filename "from" $url
    $retry_attempts = 2
    for ($i = 0; $i -lt $retry_attempts; $i++) {
        try {
            $webclient.DownloadFile($url, $filepath)
            break
        }
        Catch [Exception]{
            Start-Sleep 1
        }
    }
    if (Test-Path $filepath) {
        Write-Host "File saved at" $filepath
    } else {
        # Retry once to get the error message if any at the last try
        $webclient.DownloadFile($url, $filepath)
    }
    return $filepath
}


function ParsePythonVersion ($python_version) {
    if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
        return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
                $matches.prerelease)
    }
    $version_obj = [version]$python_version
    return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
}


function DownloadPython ($python_version, $platform_suffix) {
    $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version

    if (($major -le 2 -and $micro -eq 0) `
        -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
        ) {
        $dir = "$major.$minor"
        $python_version = "$major.$minor$prerelease"
    } else {
        $dir = "$major.$minor.$micro"
    }

    if ($prerelease) {
        if (($major -le 2) `
            -or ($major -eq 3 -and $minor -eq 1) `
            -or ($major -eq 3 -and $minor -eq 2) `
            -or ($major -eq 3 -and $minor -eq 3) `
            ) {
            $dir = "$dir/prev"
        }
    }

    if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
        $ext = "msi"
        if ($platform_suffix) {
            $platform_suffix = ".$platform_suffix"
        }
    } else {
        $ext = "exe"
        if ($platform_suffix) {
            $platform_suffix = "-$platform_suffix"
        }
    }

    $filename = "python-$python_version$platform_suffix.$ext"
    $url = "$BASE_URL$dir/$filename"
    $filepath = Download $filename $url
    return $filepath
}


function InstallPython ($python_version, $architecture, $python_home) {
    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
    if (Test-Path $python_home) {
        Write-Host $python_home "already exists, skipping."
        return $false
    }
    if ($architecture -eq "32") {
        $platform_suffix = ""
    } else {
        $platform_suffix = "amd64"
    }
    $installer_path = DownloadPython $python_version $platform_suffix
    $installer_ext = [System.IO.Path]::GetExtension($installer_path)
    Write-Host "Installing $installer_path to $python_home"
    $install_log = $python_home + ".log"
    if ($installer_ext -eq '.msi') {
        InstallPythonMSI $installer_path $python_home $install_log
    } else {
        InstallPythonEXE $installer_path $python_home $install_log
    }
    if (Test-Path $python_home) {
        Write-Host "Python $python_version ($architecture) installation complete"
    } else {
        Write-Host "Failed to install Python in $python_home"
        Get-Content -Path $install_log
        Exit 1
    }
}


function InstallPythonEXE ($exepath, $python_home, $install_log) {
    $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
    RunCommand $exepath $install_args
}


function InstallPythonMSI ($msipath, $python_home, $install_log) {
    $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
    $uninstall_args = "/qn /x $msipath"
    RunCommand "msiexec.exe" $install_args
    if (-not(Test-Path $python_home)) {
        Write-Host "Python seems to be installed else-where, reinstalling."
        RunCommand "msiexec.exe" $uninstall_args
        RunCommand "msiexec.exe" $install_args
    }
}

function RunCommand ($command, $command_args) {
    Write-Host $command $command_args
    Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
}


function InstallPip ($python_home) {
    $pip_path = $python_home + "\Scripts\pip.exe"
    $python_path = $python_home + "\python.exe"
    if (-not(Test-Path $pip_path)) {
        Write-Host "Installing pip..."
        $webclient = New-Object System.Net.WebClient
        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
        Write-Host "Executing:" $python_path $GET_PIP_PATH
        & $python_path $GET_PIP_PATH
    } else {
        Write-Host "pip already installed."
    }
}


function DownloadMiniconda ($python_version, $platform_suffix) {
    if ($python_version -eq "3.4") {
        $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
    } else {
        $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
    }
    $url = $MINICONDA_URL + $filename
    $filepath = Download $filename $url
    return $filepath
}


function InstallMiniconda ($python_version, $architecture, $python_home) {
    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
    if (Test-Path $python_home) {
        Write-Host $python_home "already exists, skipping."
        return $false
    }
    if ($architecture -eq "32") {
        $platform_suffix = "x86"
    } else {
        $platform_suffix = "x86_64"
    }
    $filepath = DownloadMiniconda $python_version $platform_suffix
    Write-Host "Installing" $filepath "to" $python_home
    $install_log = $python_home + ".log"
    $args = "/S /D=$python_home"
    Write-Host $filepath $args
    Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
    if (Test-Path $python_home) {
        Write-Host "Python $python_version ($architecture) installation complete"
    } else {
        Write-Host "Failed to install Python in $python_home"
        Get-Content -Path $install_log
        Exit 1
    }
}


function InstallMinicondaPip ($python_home) {
    $pip_path = $python_home + "\Scripts\pip.exe"
    $conda_path = $python_home + "\Scripts\conda.exe"
    if (-not(Test-Path $pip_path)) {
        Write-Host "Installing pip..."
        $args = "install --yes pip"
        Write-Host $conda_path $args
        Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
    } else {
        Write-Host "pip already installed."
    }
}

function main () {
    InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
    InstallPip $env:PYTHON
}

main


================================================
FILE: appveyor/run_with_env.cmd
================================================
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
::
:: To build extensions for 64 bit Python 2, we need to configure environment
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
::
:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
:: environment configurations.
::
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
:: cmd interpreter, at least for (SDK v7.0)
::
:: More details at:
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
:: http://stackoverflow.com/a/13751649/163740
::
:: Author: Olivier Grisel
:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
::
:: Notes about batch files for Python people:
::
:: Quotes in values are literally part of the values:
::      SET FOO="bar"
:: FOO is now five characters long: " b a r "
:: If you don't want quotes, don't include them on the right-hand side.
::
:: The CALL lines at the end of this file look redundant, but if you move them
:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
:: case, I don't know why.
@ECHO OFF

SET COMMAND_TO_RUN=%*
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf

:: Extract the major and minor versions, and allow for the minor version to be
:: more than 9.  This requires the version number to have two dots in it.
SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
IF "%PYTHON_VERSION:~3,1%" == "." (
    SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
) ELSE (
    SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
)

:: Based on the Python version, determine what SDK version to use, and whether
:: to set the SDK for 64-bit.
IF %MAJOR_PYTHON_VERSION% == 2 (
    SET WINDOWS_SDK_VERSION="v7.0"
    SET SET_SDK_64=Y
) ELSE (
    IF %MAJOR_PYTHON_VERSION% == 3 (
        SET WINDOWS_SDK_VERSION="v7.1"
        IF %MINOR_PYTHON_VERSION% LEQ 4 (
            SET SET_SDK_64=Y
        ) ELSE (
            SET SET_SDK_64=N
            IF EXIST "%WIN_WDK%" (
                :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
                REN "%WIN_WDK%" 0wdf
            )
        )
    ) ELSE (
        ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
        EXIT 1
    )
)

IF %PYTHON_ARCH% == 64 (
    IF %SET_SDK_64% == Y (
        ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
        SET DISTUTILS_USE_SDK=1
        SET MSSdk=1
        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
        ECHO Executing: %COMMAND_TO_RUN%
        call %COMMAND_TO_RUN% || EXIT 1
    ) ELSE (
        ECHO Using default MSVC build environment for 64 bit architecture
        ECHO Executing: %COMMAND_TO_RUN%
        call %COMMAND_TO_RUN% || EXIT 1
    )
) ELSE (
    ECHO Using default MSVC build environment for 32 bit architecture
    ECHO Executing: %COMMAND_TO_RUN%
    call %COMMAND_TO_RUN% || EXIT 1
)


================================================
FILE: appveyor.yml
================================================
environment:
  HDF5_LIBDIR: C:\HDF5

  global:
    # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
    # /E:ON and /V:ON options are not enabled in the batch script intepreter
    # See: http://stackoverflow.com/a/13751649/163740
    CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"

  matrix:

    - PYTHON: "C:\\Python27-x64"
      PYTHON_VERSION: "2.7.x" # currently 2.7.9
      PYTHON_ARCH: "64"


    # Python 2.7.10 is the latest version and is not pre-installed.
    - PYTHON: "C:\\Python27.10-x64"
      PYTHON_VERSION: "2.7.10"
      PYTHON_ARCH: "64"


    - PYTHON: "C:\\Python27.10"
      PYTHON_VERSION: "2.7.10"
      PYTHON_ARCH: "32"

    # Pre-installed Python versions, which Appveyor may upgrade to
    # a later point release.
    # See: http://www.appveyor.com/docs/installed-software#python
    - PYTHON: "C:\\Python27"
      PYTHON_VERSION: "2.7.x" # currently 2.7.9
      PYTHON_ARCH: "32"

    # Major and minor releases (i.e x.0.0 and x.y.0) prior to 3.3.0 use
    # a different naming scheme.

    #- PYTHON: "C:\\Python270"
    #  PYTHON_VERSION: "2.7.0"
    #  PYTHON_ARCH: "32"
    #
    #- PYTHON: "C:\\Python270-x64"
    #  PYTHON_VERSION: "2.7.0"
    #  PYTHON_ARCH: "64"

install:
  # If there is a newer build queued for the same PR, cancel this one.
  # The AppVeyor 'rollout builds' option is supposed to serve the same
  # purpose but it is problematic because it tends to cancel builds pushed
  # directly to master instead of just PR builds (or the converse).
  # credits: JuliaLang developers.
  - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
        https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
        Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
          throw "There are newer queued builds for this pull request, failing early." }
  - ECHO "Filesystem root:"
  - ps: "ls \"C:/\""

  - ECHO "Installed SDKs:"
  - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""

  # Install Python (from the official .msi of http://python.org) and pip when
  # not already installed.
  #- ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
  - ps: "appveyor\\install.ps1"

   # https://github.com/aldanor/hdf5-rs/blob/master/appveyor.yml
  - cmd: mkdir C:\HDF5
   #- cmd: mkdir C:\HDF5\lib
   #- ps: Invoke-WebRequest "https://github.com/kkirstein/hdf5-rs/releases/download/alpha/hdf5.dll" -OutFile "C:\HDF5\lib\hdf5.dll"
   #- cmd: set PATH=C:\HDF5\bin;%PATH%
   #- cmd: set PATH=C:\HDF5\bin;%PATH%
   #- ps: Invoke-WebRequest "https://github.com/kkirstein/hdf5-rs/releases/download/alpha/hdf5.dll" -OutFile "C:\HDF5\lib\hdf5.dll"

  # Prepend newly installed Python to the PATH of this build (this cannot be
  # done from inside the powershell script as it would require to restart
  # the parent CMD process).
  - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%;C:\\HDF5"

    # Check that we have the expected version and architecture for Python
  - "python --version"
  - "python -c \"import struct; print(struct.calcsize('P') * 8)\""

  # Upgrade to the latest version of pip to avoid it displaying warnings
  # about it being out of date.
  - "pip install --disable-pip-version-check --user --upgrade pip"

  - "%CMD_IN_ENV% pip install wheel"
  - "%CMD_IN_ENV% pip install nose"

  # Install the build dependencies of the project. If some dependencies contain
  # compiled extensions and are not provided as pre-built wheel packages,
  # pip will build them from source using the MSVC compiler matching the
  # target Python version and architecture
  #
  - ps: if ($env:PYTHON_ARCH -eq "32") { `
        Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/h5py-2.5.0-cp27-none-win32.whl" -OutFile "C:\HDF5\h5py-2.5.0-cp27-none-win32.whl";
        pip install C:\HDF5\h5py-2.5.0-cp27-none-win32.whl `
        } else { `
        Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/h5py-2.5.0-cp27-none-win_amd64.whl" -OutFile "C:\HDF5\h5py-2.5.0-cp27-none-win_amd64.whl";
        pip install C:\HDF5\h5py-2.5.0-cp27-none-win_amd64.whl `
        }

  - ps: if ($env:PYTHON_ARCH -eq "32") { `
        Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/matplotlib-1.5.1-cp27-none-win32.whl" -OutFile "C:\HDF5\matplotlib-1.5.1-cp27-none-win32.whl";
        pip install C:\HDF5\matplotlib-1.5.1-cp27-none-win32.whl `
        } else { `
        Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/matplotlib-1.5.1-cp27-none-win_amd64.whl" -OutFile "C:\HDF5\matplotlib-1.5.1-cp27-none-win_amd64.whl";
        pip install C:\HDF5\matplotlib-1.5.1-cp27-none-win_amd64.whl `
        }

  #- ps: Invoke-WebRequest "https://pypi.python.org/packages/2.7/h/h5py/h5py-2.5.0.win32-py2.7.exe" -OutFile "C:\HDF5\h5py-2.5.0.win32-py2.7.exe"
  #- ps: Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/h5py-2.5.0-cp27-none-win%PYTHON_ARCH%.whl" -OutFile "C:\HDF5\h5py-2.5.0-cp27-none-win%PYTHON_ARCH%.whl"
    #- "%CMD_IN_ENV% C:\\HDF5\\h5py-2.5.0.win32-py2.7.exe"
    #- "%CMD_IN_ENV% pip install C:\\HDF5\\h5py-2.5.0-cp27-none-win.whl"
    #- "%CMD_IN_ENV% pip install -r requirements.txt"
    #
    #- ps: Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/matplotlib-1.5.1-cp27-none-win32.whl" -OutFile "C:\HDF5\matplotlib-1.5.1-cp27-none-win32.whl"
    #- "%CMD_IN_ENV% C:\\HDF5\\h5py-2.5.0.win32-py2.7.exe"
    #- "%CMD_IN_ENV% pip install C:\\HDF5\\matplotlib-1.5.1-cp27-none-win32.whl"


  - ps: Invoke-WebRequest "http://www.lfd.uci.edu/~gohlke/pythonlibs/djcobkfp/seaborn-0.7.0-py2.py3-none-any.whl" -OutFile "C:\HDF5\seaborn-0.7.0-py2.py3-none-any.whl"
    #- "%CMD_IN_ENV% C:\\HDF5\\h5py-2.5.0.win32-py2.7.exe"
  - ps: pip install C:\\HDF5\\seaborn-0.7.0-py2.py3-none-any.whl


build_script:
  # Build the compiled extension
  - "%CMD_IN_ENV% python setup.py build"
  - "%CMD_IN_ENV% python setup.py install"

test_script:
  # Run the project tests
  - "%CMD_IN_ENV% python setup.py nosetests"

after_test:
  # If tests are successful, create binary packages for the project.
  - "%CMD_IN_ENV% python setup.py bdist_wheel"
  - "%CMD_IN_ENV% python setup.py bdist_wininst"
  - "%CMD_IN_ENV% python setup.py bdist_msi"
  - ps: "ls dist"

artifacts:
  # Archive the generated packages in the ci.appveyor.com build report.
  - path: dist\*


================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest

help:
	@echo "Please use \`make <target>' where <target> is one of"
	@echo "  html       to make standalone HTML files"
	@echo "  dirhtml    to make HTML files named index.html in directories"
	@echo "  singlehtml to make a single large HTML file"
	@echo "  pickle     to make pickle files"
	@echo "  json       to make JSON files"
	@echo "  htmlhelp   to make HTML files and a HTML help project"
	@echo "  qthelp     to make HTML files and a qthelp project"
	@echo "  devhelp    to make HTML files and a Devhelp project"
	@echo "  epub       to make an epub"
	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
	@echo "  text       to make text files"
	@echo "  man        to make manual pages"
	@echo "  changes    to make an overview of all changed/added/deprecated items"
	@echo "  linkcheck  to check all external links for integrity"
	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"

clean:
	-rm -rf $(BUILDDIR)/*

html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/track.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/track.qhc"

devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/track"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/track"
	@echo "# devhelp"

epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	make -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."


================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../'))

#from poretools import __version__ as version
version = '0.5.1'
# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
              'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['templates']

# The suffix of source filenames.
source_suffix = '.rst'

# The encoding of source files.
# source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'poretools'
copyright = u'2014'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = version
# The full version, including alpha/beta/rc tags.
release = version

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']

# The reST default role (used for this markup: `text`) to use for all documents.
# default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []


# -- Options for HTML output ---------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'default'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ["themes"]

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
html_short_title = project + " v" + release

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = 'gemini.png'

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = ''
#html_style = ''

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {
#    'index': ['sidebar-intro.html', 'sourcelink.html', 'searchbox.html']
#}


# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}

# If false, no module index is generated.
# html_domain_indices = True

# If false, no index is generated.
# html_use_index = True

# If true, the index is split into individual pages for each letter.
# html_split_index = False

# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
html_show_sphinx = False

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'poretools-docs'

# Google analytics
# googleanalytics_id = "UA-24167610-15"

# -- Options for LaTeX output --------------------------------------------------

# The paper size ('letter' or 'a4').
# latex_paper_size = 'letter'

# The font size ('10pt', '11pt' or '12pt').
# latex_font_size = '10pt'

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
    ('index', 'poretools.tex', u'poretools Documentation', u'Nick Loman and Aaron Quinlan', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False

# If true, show page references after internal links.
# latex_show_pagerefs = False

# If true, show URL addresses after external links.
# latex_show_urls = False

# Additional stuff for the LaTeX preamble.
# latex_preamble = ''

# Documents to append as an appendix to all manuals.
# latex_appendices = []

# If false, no module index is generated.
# latex_domain_indices = True


# -- Options for manual page output --------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('index', 'gemini', u'poretools Documentation', [u'Nick Loman and Aaron Quinlan'], 1)
]


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}


class Mock(object):
    def __init__(self, *args, **kwargs):
        pass

    def __call__(self, *args, **kwargs):
        return Mock()

    @classmethod
    def __getattr__(cls, name):
        if name in ('__file__', '__path__'):
            return '/dev/null'
        elif name[0] == name[0].upper():
            return type(name, (), {})
        else:
            return Mock()

MOCK_MODULES = []
for mod_name in MOCK_MODULES:
    sys.modules[mod_name] = Mock()


================================================
FILE: docs/content/examples.rst
================================================
###############
Usage examples
###############

.. note::

   In the following examples, ``test_data`` can be replaced with the directory containing the FAST5 files
   from your own runs. If you are new to ONT sequencing, the ``test_data`` directory is shipped with ``poretools``
   for experimentation.

===================
poretools ``fastq``
===================
Extract sequences in FASTQ format from a set of FAST5 files.

.. code-block:: bash

    poretools fastq test_data/*.fast5

Or, if there are too many files for your OS to do the wildcard expansion, just provide a directory.
``poreutils`` will automatically find all of the FAST5 files in the directory.

.. code-block:: bash

    poretools fastq test_data/


Extract sequences in FASTQ format from a set of FAST5 files.
    
.. code-block:: bash

    poretools fastq test_data/
    poretools fastq --min-length 5000 test_data/
    poretools fastq --max-length 5000 test_data/
    poretools fastq --type all test_data/
    poretools fastq --type fwd test_data/
    poretools fastq --type rev test_data/
    poretools fastq --type 2D test_data/
    poretools fastq --type fwd,rev test_data/


A type of "best" will extract the 2D read, if it exists. If not, it will extract either the template or complement read, whichever is available and has a better average Phred score.

.. code-block:: bash

    poretools fastq --type best test_data/


Only extract sequence with more complement events than template. These are the so-called "high quality 2D reads" and are the most accurate sequences from a 
given run.

.. code-block:: bash

    poretools fastq --type 2D --high-quality test_data/

The data in fastq format are returned in standard output.

===================
poretools ``fasta``
===================
Extract sequences in FASTA format from a set of FAST5 files.

.. code-block:: bash

    poretools fasta test_data/
    poretools fasta --min-length 5000 test_data/
    poretools fasta --max-length 5000 test_data/
    poretools fasta --type all test_data/
    poretools fasta --type fwd test_data/
    poretools fasta --type rev test_data/
    poretools fasta --type 2D test_data/
    poretools fasta --type fwd,rev test_data/
    poretools fasta --type best test_data/

The data in fasta format are returned in standard output.

=====================
poretools ``combine``
=====================
Create a tarball from a set of FAST5 (HDF5) files.

.. code-block:: bash

    # plain tar (recommended for speed)
    poretools combine -o foo.fast5.tar test_data/*.fast5

    # gzip
    poretools combine -o foo.fast5.tar.gz test_data/*.fast5

    # bzip2
    poretools combine -o foo.fast5.tar.bz2 test_data/*.fast5

========================
poretools ``yield_plot``
========================
Create a collector's curve reflecting the sequencing yield over time for a set of reads. There are two types of plots. The first is the yield of reads over time:

.. code-block:: bash

    poretools yield_plot --plot-type reads test_data/2016*fast5

The result should look something like:\

.. image:: _images/yield.reads.png
    :width: 400pt
    
The second is the yield of base pairs over time:

.. code-block:: bash

    poretools yield_plot --plot-type basepairs test_data/2016*fast5

The result should look something like:
    
.. image:: _images/yield.bp.png
    :width: 400pt

Of course, you can save to PDF or PNG with `--saveas`:

.. code-block:: bash

    poretools yield_plot \
              --plot-type basepairs \
              --saveas foo.pdf\
              test_data/

    poretools yield_plot \
              --plot-type basepairs \
              --saveas foo.png\
              test_data/

If you don't like the default aesthetics, try `--theme-bw`:

.. code-block:: bash

    poretools yield_plot --theme-bw test_data/


======================
poretools ``squiggle``
======================
Make a "squiggle" plot of the signal over time for a given read or set of reads

.. code-block:: bash

    poretools squiggle test_data/foo.fast5


The result should look something like:

.. image:: _images/foo.fast5.png
    :width: 400pt

If you don't like the default aesthetics, try `--theme-bw`:

.. code-block:: bash

    poretools squiggle --theme-bw test_data/


Other options:

.. code-block:: bash

    # save as PNG
    poretools squiggle --saveas png test_data/foo.fast5

    # save as PDF
    poretools squiggle --saveas pdf test_data/foo.fast5

    # make a PNG for each FAST5 file in a directory
    poretools squiggle --saveas png test_data/

====================
poretools ``winner``
====================
Report the longest read among a set of FAST5 files.

.. code-block:: bash

    poretools winner test_data/
    poretools winner --type all test_data/
    poretools winner --type fwd test_data/
    poretools winner --type rev test_data/
    poretools winner --type 2D test_data/
    poretools winner --type fwd,rev test_data/
    poretools winner --type best test_data/

===================
poretools ``stats``
===================
Collect read size statistics from a set of FAST5 files.

.. code-block:: bash

    poretools stats test_data/
    total reads 2286.000000
    total base pairs    8983574.000000
    mean    3929.822397
    median  4011.500000
    min 13.000000
    max 6864.000000

===================
poretools ``hist``
===================
Plot a histogram of read sizes from a set of FAST5 files.

.. code-block:: bash

    poretools hist test_data/
    poretools hist --min-length 1000 --max-length 10000 test_data/

    poretools hist --num-bins 20 --max-length 10000 test_data/

If you don't like the default aesthetics, try `--theme-bw`:

.. code-block:: bash

    poretools hist --theme-bw test_data/

The result should look something like:

.. image:: _images/hist.png
    :width: 400pt    

=====================
poretools ``nucdist``
=====================
Look at the nucleotide composition of a set of FAST5 files.

.. code-block:: bash
 
    poretools nucdist test_data/
    A   78287   335291  0.233489714904
    C   75270   335291  0.224491561062
    T   92575   335291  0.276103444471
    G   84754   335291  0.252777438106
    N   4405    335291  0.0131378414571

======================
poretools ``qualdist``
======================
Look at the quality score composition of a set of FAST5 files.

.. code-block:: bash

    poretools qualdist test_data/
    !   0   83403   335291  0.248748102395
    "   1   46151   335291  0.137644613187
    #   2   47463   335291  0.141557632027
    $   3   34471   335291  0.102809201559
    %   4   24879   335291  0.0742012162569
    &   5   20454   335291  0.0610037251224
    '   6   16783   335291  0.0500550268274
    (   7   13699   335291  0.0408570465655
    )   8   11356   335291  0.0338690868529
    *   9   9077    335291  0.0270720061081
    +   10  6492    335291  0.0193622852984
    ,   11  4891    335291  0.014587328619
    -   12  3643    335291  0.0108651887465
    .   13  2585    335291  0.00770972080968
    /   14  1969    335291  0.0058725107444
    0   15  1475    335291  0.00439916371152
    1   16  1146    335291  0.00341792651756
    2   17  902 335291  0.00269020045274
    3   18  790 335291  0.00235616225905
    4   19  619 335291  0.0018461575169
    5   20  532 335291  0.00158668142002
    6   21  440 335291  0.00131229290378
    7   22  397 335291  0.00118404609727
    8   23  379 335291  0.00113036138757
    9   24  313 335291  0.000933517452004
    :   25  327 335291  0.000975272226215
    ;   26  138 335291  0.000411582774366
    <   27  121 335291  0.000360880548538
    =   28  96  335291  0.000286318451733
    >   29  76  335291  0.000226668774289
    ?   30  69  335291  0.000205791387183
    @   31  61  335291  0.000181931516205
    A   32  48  335291  0.000143159225866
    B   33  23  335291  6.8597129061e-05
    C   34  14  335291  4.17547742111e-05
    D   35  6   335291  1.78949032333e-05
    F   37  3   335291  8.94745161666e-06

======================
poretools ``qualpos``
======================
Produce a box-whisker plot of qualoty score distribution over positions in reads.

.. code-block:: bash

    poretools qualpos test_data/

The result should look something like:

.. image:: _images/qualpos.png
    :width: 400pt 

=====================
poretools ``tabular``
=====================
Dump the length, name, seq, and qual of the sequence in one or a set of FAST5 files.

.. code-block:: bash

    poretools tabular foo.fast5 
    length  name    sequence    quals
    10    @channel_100_read_14_complement   GTCCCCAACAACAC    $%%'"$"%!)

====================
poretools ``events``
====================
Extract the raw nanopore events from each FAST5 file.

.. code-block:: bash

    poretools events test_data/ | head -5
    file    strand  mean    start   stdv    length  model_state model_level move    p_model_state   mp_model_state  p_mp_model_state    p_A p_C p_G p_T raw_index
    test_data/2016_3_4_3507_1_ch120_read240_strand.fast5    template    58.3245290305   1559.89409031   1.34165996292   0.0146082337317 CGACTT  58.1304809188   0   0.0226559   CATCTT  0.0229866   0.284469    0.130683    0.137386    0.447461
    test_data/2016_3_4_3507_1_ch120_read240_strand.fast5    template    50.1420877511   1559.90869854   0.921372775302  0.0348605577689 GACTTT  49.3934875964   1   0.0849836   GACTTT  0.0849836   0.257314    0.350541    0.101351    0.290794
    test_data/2016_3_4_3507_1_ch120_read240_strand.fast5    template    47.5841029424   1559.9435591    0.771398562801  0.00763612217795    ACTTTG  48.2080162623   1   0.108899    TCTTTG  0.13079 0.000477931 0.00853333  0.306356    0.684632
    test_data/2016_3_4_3507_1_ch120_read240_strand.fast5    template    51.5879264562   1559.95119522   0.684238307171  0.0112881806109 CTTTGA  52.7784154546   1   0.110625    CTTTGG  0.121103    4.69995e-06 0.00382846  0.0169048   0.979262

Extract the pre-basecalled events from each FAST5 file. 

.. code-block:: bash

    poretools events --pre-basecalled test_data/ | head -5
    file    strand  mean    start   stdv    length  model_state     model_level     move    p_model_state   mp_model_state  p_mp_model_state        p_A     p_C     p_G     p_T     raw_index
    burn-in-run-2/ch100_file15_strand.fast5     pre_basecalled  51.4652695313   5352344 0.655003995591      35
    burn-in-run-2/ch100_file15_strand.fast5     pre_basecalled  60.1776123047   5352379 1.05143911309       18
    burn-in-run-2/ch100_file15_strand.fast5     pre_basecalled  48.9152374359   5352397 0.864834628834      67
    burn-in-run-2/ch100_file15_strand.fast5     pre_basecalled  55.4002178596   5352464 1.75915620083       17    

===================
poretools ``times``
===================

.. code-block:: bash

    poretools times test_data/ | head -5
    channel filename    read_length exp_starttime   unix_timestamp  duration    unix_timestamp_end  iso_timestamp   day hour    minute
    120 test_data/2016_3_4_3507_1_ch120_read240_strand.fast5    5826    1457127309  1457128868  47  1457128915  2016-03-04T15:01:08-0700    04  15  01
    120 test_data/2016_3_4_3507_1_ch120_read353_strand.fast5    3399    1457127309  1457129863  28  1457129891  2016-03-04T15:17:43-0700    04  15  17
    120 test_data/2016_3_4_3507_1_ch120_read415_strand.fast5    2640    1457127309  1457130808  24  1457130832  2016-03-04T15:33:28-0700    04  15  33
    120 test_data/2016_3_4_3507_1_ch120_read418_strand.fast5    3487    1457127309  1457130851  31  1457130882  2016-03-04T15:34:11-0700    04  15  34

=======================
poretools ``occupancy``
=======================
Plot the throughput performance of each pore on the flowcell during a given sequencing run.

.. code-block:: bash

    poretools occupancy test_data/

The result should look something like:

.. image:: _images/occupancy.png
    :width: 400pt  


===================
poretools ``index``
===================
Tabulate all file location info and metadata such as ASIC ID and temperature from a set of FAST5 files

.. code-block:: bash

    poretools index test_data | head -5 | column -t
    source_filename                                       template_fwd_length  complement_rev_length  2d_length  asic_id     asic_temp  heatsink_temp  channel  exp_start_time  exp_start_time_string_date  exp_start_time_string_time  start_time  start_time_string_date  start_time_string_time  duration  fast5_version
    test_data/2016_3_4_3507_1_ch120_read240_strand.fast5  5826                 5011                   5079       3571011476  30.37      36.99          120      1457127309      2016-Mar-04                 (Fri)                       14:35:09    1457128868              2016-Mar-04             (Fri)     15:01:08       47  metrichor1.16
    test_data/2016_3_4_3507_1_ch120_read353_strand.fast5  3399                 2962                   2940       3571011476  30.37      36.99          120      1457127309      2016-Mar-04                 (Fri)                       14:35:09    1457129863              2016-Mar-04             (Fri)     15:17:43       28  metrichor1.16
    test_data/2016_3_4_3507_1_ch120_read415_strand.fast5  2640                 2244                   2428       3571011476  30.37      36.99          120      1457127309      2016-Mar-04                 (Fri)                       14:35:09    1457130808              2016-Mar-04             (Fri)     15:33:28       24  metrichor1.16
    test_data/2016_3_4_3507_1_ch120_read418_strand.fast5  3487                 2950                   3384       3571011476  30.37      36.99          120      1457127309      2016-Mar-04                 (Fri)                       14:35:09    1457130851              2016-Mar-04             (Fri)     15:34:11       31  metrichor1.16


======================
poretools ``metadata``
=======================
Extract the metadata from the fast5 file

.. code-block:: bash

    poretools metadata  013731_11rx_v2_3135_1_ch20_file19_strand.fast5

    asic_id asic_temp   heatsink_temp
    31037   28.11   37.88

    poretools metadata --read  013731_11rx_v2_3135_1_ch20_file19_strand.fast5
    filename    scaling_used    abasic_peak_height  hairpin_polyt_level median_before   start_time  read_id read_number hairpin_peak_height abasic_found    abasic_event_index  duration    start_mux   hairpin_found   hairpin_event_index
    013731_11rx_v2_3135_1_ch20_file19_strand.fast5    1   124.31769966    0.413218809334  226.393825112   4648221 3b4e45bf-6d42-45bc-9314-1d8a630971c2    19  125.783167256   1   2   195322  4   1   1478






================================================
FILE: docs/content/help.rst
================================================
##########
Options
##########

The following demonstrates the options available in ``poretools``.

.. code-block:: bash

    poretools --help
    usage: poretools [-h] [-v]

                     {combine,fastq,fasta,stats,hist,events,readstats,tabular,nucdist,qualdist,winner,wiggle,times}
                     ...

    optional arguments:
      -h, --help            show this help message and exit
      -v, --version         Installed poretools version

    [sub-commands]:
      {combine,fastq,fasta,stats,hist,events,readstats,tabular,nucdist,qualdist,winner,wiggle,times}
        combine             Combine a set of FAST5 files in a TAR achive
        fastq               Extract FASTQ sequences from a set of FAST5 files
        fasta               Extract FASTA sequences from a set of FAST5 files
        stats               Get read size stats for a set of FAST5 files
        hist                Plot read size histogram for a set of FAST5 files
        events              Extract each nanopore event for each read
        readstats           Extract signal information for each read over time.
        tabular             Extract the lengths and name/seq/quals from a set of
                            FAST5 files in TAB delimited format
        nucdist             Get the nucl. composition of a set of FAST5 files
        qualdist            Get the qual score composition of a set of FAST5 files
        winner              Get the longest read from a set of FAST5 files
        squiggle            Plot the observed signals for FAST5 reads
        times               Return the start times from a set of FAST5 files in
                            tabular format
        yield_plot          Plot the yield over time for a set of FAST5 files

================================================
FILE: docs/content/history.rst
================================================
###############
Release History
###############

Version 0.6.0 (29-Aug-2016)
============================
0. Added new ``organise`` command to place FAST5 files into a useful folder hierarchy
1. Updated the logic for event timing to handle both R9 and earlier FAST5 files.
2. Added a "best" option to the ``fasta`` and ``fastq`` tools to identify the best sequence for a read (of 2d, template, complement).
3. Added R9 RNN support.
4. Various updates to API to accommodate the R9 changes made to the HDF5 structure.

================================================
FILE: docs/content/installation.rst
================================================
############
Installation
############


====================
Basic Installation
====================
.. code-block:: bash

	git clone https://github.com/arq5x/poretools
	cd poretools

Install as root:

.. code-block:: bash

	python setup.py install

Install as a plain old user who has root access:

.. code-block:: bash

	sudo python setup.py install

Install as a plain old who lacks ``sudo`` privileges:

.. code-block:: bash

	# details: https://docs.python.org/2/install/index.html#alternate-installation-the-user-scheme
	python setup.py install --user

	# now update your PATH such that it includes the directory to which poretools was just copied.
	# look for a line in the installation log like: Installing poretools script to /home/arq5x/.local/bin
        # in this case, I would either add that path to the PATH environment variable for the current session:
        export PATH=$PATH:/home/arq5x/.local/bin

        # or, better yet add it to your .bashrc file.
        # at this point you should be able to run the poretools executable from anywhere on your system.
        poretools --help

=================================
Installing on Windows with MinKNOW installed
=================================

MinKNOW installs the Anaconda distribution of Python, which means that h5py, matplotlib, and pandas are already installed.

However, currently MinKNOW does not update the Windows registry to specify that Anaconda is the default version of Python, which makes installing packages tricky. To address this, some changes need to be made to the registry. This can be fixed by downloading the following file:

	<https://raw.githubusercontent.com/arq5x/poretools/master/dist/poretools.reg>

Ensure it is named 'poretools.reg' and then run it (by double-clicking). Windows will prompt you about making changes to the registry, which you should agree to.

Now, you need to install seaborn, which is the plotting package that ``poretools`` uses as a replacement for R and rpy2 as of version ``0.5.1``.

    conda install seaborn

If conda cannot install seaborn, you could consider installing ``pip`` and running:

    pip install seaborn

Then, to install poretools, simply download and run the Windows installer:

        <https://github.com/arq5x/poretools/blob/master/dist/poretools-0.5.1.win-amd64.exe?raw=true>


=================================
Installing on OS X
=================================

First, you should install a proper package manager for OS X. In our experience, `HomeBrew <http://brew.sh/>`_ works extremely well.

To install HomeBrew, you run the following command (lifted from the HomeBrew site):

.. code-block:: bash

	ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

Using HomeBrew, install HDF5 from the HomeBrew Science "tap";

.. code-block:: bash

	brew tap homebrew/science
	brew install hdf5

You will also need Cython and numpy packages (if they are not already installed):

.. code-block:: bash

	pip install cython
	pip install numpy
	
Now, you will need to install the R statistical analysis software (you may already have this...). The `CRAN <http://cran.r-project.org/bin/macosx/>`_ website houses automatic installation packages for different versions of OS X.  Here are links to such packages for `Snow Leopard and higher <http://cran.r-project.org/bin/macosx/R-3.1.1-snowleopard.pkg>`_ as well as `Mavericks <http://cran.r-project.org/bin/macosx/R-3.1.1-mavericks.pkg>`_.

At this point, you can install poretools.

.. code-block:: bash

	git clone https://github.com/arq5x/poretools
	cd poretools

Install as an administrator of your machine:

.. code-block:: bash

	sudo python setup.py install

Install as a plain old who lacks ``sudo`` priveleges:

.. code-block:: bash

	# details: https://docs.python.org/2/install/index.html#alternate-installation-the-user-scheme
	python setup.py install --user

=================================
Installing dependencies on Ubuntu
=================================

Package dependencies

.. code-block:: bash

	sudo apt-get install git python-setuptools python-dev cython libhdf5-serial-dev

Then install R 3.0, this requires a bit of hacking. You need to replace 'precise' with the appropriate version if you are on a different Ubuntu version, see <http://cran.r-project.org/bin/linux/ubuntu/README> for more details.

.. code-block:: bash

	sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9

Open in a text editor (as sudo) the file ``/etc/apt/sources.list`` and add the following line to the bottom, for Ubuntu 12.04:

.. code-block:: bash

	deb http://www.stats.bris.ac.uk/R/bin/linux/ubuntu precise/

Or, for Ubuntu 14.04:

.. code-block:: bash

	deb http://www.stats.bris.ac.uk/R/bin/linux/ubuntu trusty/

Then install poretools, finally:

.. code-block:: bash

	git clone https://github.com/arq5x/poretools
	cd poretools
	sudo python setup.py install
	poretools

============
In the cloud
============

Amazon Web Services machine image ID: ami-4c0ec424

==========
Via docker
==========

Build the docker container yourself (preferred):

.. code-block:: bash

	git clone https://github.com/arq5x/poretools
	cd poretools
	docker build -t poretools .
	docker run poretools --help

Or use the pre-built `image from Docker Hub <https://registry.hub.docker.com/u/stephenturner/poretools/>`_:

.. code-block:: bash

	docker pull stephenturner/poretools
	docker run stephenturner/poretools --help

To run the poretools container on data residing on the host machine, run ``docker run -h`` and look at the help for the ``-v`` option.


================================================
FILE: docs/content/notebook.rst
================================================
################
IPython Notebook
################

An IPython notebook demonstrating the functionality and output of ``poretools`` is available in the repository. 
Use this link to view it via the ``nbviewer`` service: 
<http://nbviewer.ipython.org/github/arq5x/poretools/blob/master/poretools/ipynb/test_run_report.ipynb>


================================================
FILE: docs/index.rst
================================================
==========================================================================================
**poretools**: *a toolkit for working with nanopore sequencing data from Oxford Nanopore.*
==========================================================================================
The MinION (TM) from Oxford Nanopore Technologies (ONT) is the first nanopore sequencer to be 
commercialised and is now available to early-access users. The MinION (TM) is a USB-connected, 
portable nanopore sequencer which permits real-time analysis of streaming event data. 
Currently, the research community lacks a standardized toolkit for the analysis of nanopore datasets.

We have therefore develped ``poretools``, a flexible toolkit for exploring datasets generated by 
nanopore sequencing devices from MinION for the purposes of quality control and downstream analysis. 
``Poretools`` operates directly on the native FAST5 (a variant of the HDF5 standard) file format produced 
by ONT and provides a wealth of format conversion utilities and data exploration and visualization tools. 

A preprint of the ``poretools`` manuscript is available on bioarxiv: http://biorxiv.org/content/early/2014/07/23/007401

Below are a few examples of common usage.

1. Extract sequences in FASTQ format from a set of FAST5 files.
    
.. code-block:: bash

    poretools fastq fast5/

2. Make a collector's curve of the yield from a sequencing run.

.. code-block:: bash

    poretools yield_plot --plot-type reads fast5/

3. Plot a histogram of read sizes from a set of FAST5 files.

.. code-block:: bash

    poretools hist fast5/

=================
Table of contents
=================

.. toctree::
   :maxdepth: 3

   content/installation
   content/help
   content/notebook
   content/examples
   content/history

=================
Requirements
=================
  - HDF5 >= 1.8.7 (http://www.hdfgroup.org/HDF5/)
  - Python >= 2.7
  - h5py >= 2.0.0
  - matplotlib
  - seaborn
  - pandas

.. note::
    Please note that Anaconda and Python(x,y) already have all these dependencies installed:
    Anaconda (Linux, Windows, OS X): https://store.continuum.io/cshop/anaconda/ Python(x,y) (Windows): https://code.google.com/p/pythonxy/




================================================
FILE: docs/requirements.txt
================================================
sphinx


================================================
FILE: poretools/Event.py
================================================
class Event(object):
	"""
	Very basic class to represent a nanopore 
	translocation event for a single pore
	based upon data in the Events table of 
	a Oxford Nanopore FAST5 (HDF5) file
	"""
	def __init__(self, row):
		self.row = row
		try:
			self.mean = row['mean']
		except Exception:
			self.mean = ""
		try:
			self.start = row['start']
		except Exception:
			self.start = ""
		try:
			self.stdv = row['stdv']
		except Exception:
			self.stdv = ""
		try:
			self.length = row['length']
		except Exception:
			self.length = ""
		try:
			self.model_state = row['model_state']
		except Exception:
			self.model_state = ""
		try:
			self.model_level = row['model_level']
		except Exception:
			self.model_level = ""
		try:
			self.move = row['move']
		except Exception:
			self.move = ""
		try:
			self.p_model_state = row['p_model_state']
		except Exception:
			self.p_model_state = ""
		try:
			self.mp_state = row['mp_state']
		except Exception:
			self.mp_state = ""
		try:
			self.p_mp_state = row['p_mp_state']
		except Exception:
			self.p_mp_state = ""
		try:
			self.p_A = row['p_A']
		except Exception:
			self.p_A = ""
		try:
			self.p_C = row['p_C']
		except Exception:
			self.p_C = ""
		try:
			self.p_G = row['p_G']
		except Exception:
			self.p_G = ""
		try:
			self.p_T = row['p_T']
		except Exception:
			self.p_T = ""

	def __repr__(self):
		return '\t'.join([str(s) for s in [self.mean, self.start, self.stdv,
										   self.length, self.model_state,
										   self.model_level, self.move,
										   self.p_model_state, 
										   self.mp_state, self.p_mp_state,
										   self.p_A, self.p_C, 
										   self.p_G, self.p_T]])


================================================
FILE: poretools/Fast5File.py
================================================
import sys
import os
import glob
import tarfile
import shutil
import h5py
import dateutil.parser
import datetime
import time

#logging
import logging
logger = logging.getLogger('poretools')

### Some notes on nanopore FAST5 file format:
### start_time used to be represented in seconds, when stored in the /Analyses subdirectories.
### more recently with MinKNOW updates start_time is stored as number of samples under /Reads/Raw
### and must be converted to seconds by dividing by sample frequency.

# poretools imports
import formats
from Event import Event

fastq_paths = {
  'closed' : {},
  'r9rnn' :         { 'template' : '/Analyses/Basecall_RNN_1D_%03d/BaseCalled_template'},
  'metrichor1.16' : { 'template' : '/Analyses/Basecall_1D_%03d/BaseCalled_template',
                      'complement' : '/Analyses/Basecall_1D_%03d/BaseCalled_complement',
                      'twodirections' : '/Analyses/Basecall_2D_%03d/BaseCalled_2D',
                      'pre_basecalled' : '/Analyses/EventDetection_000/Reads/'
                    },
  'classic' :       { 'template' : '/Analyses/Basecall_2D_%03d/BaseCalled_template',
                      'complement' : '/Analyses/Basecall_2D_%03d/BaseCalled_complement',
                      'twodirections' : '/Analyses/Basecall_2D_%03d/BaseCalled_2D',
                      'pre_basecalled' : '/Analyses/EventDetection_000/Reads/'
                    },
  'prebasecalled' : {'pre_basecalled' : '/Analyses/EventDetection_000/Reads/'}
}

FAST5SET_FILELIST = 0
FAST5SET_DIRECTORY = 1
FAST5SET_SINGLEFILE = 2
FAST5SET_TARBALL = 3
PORETOOLS_TMPDIR = '.poretools_tmp'


class Fast5DirHandler(object):

    patterns = ["*.fast5"]

    def __init__(self, dir):
        self.dir = dir
        self.files = []
        super(Fast5DirHandler, self).__init__()

        
        if os.path.isdir(self.dir):
            pattern = self.dir + os.path.sep + '*.fast5'
            files = glob.glob(pattern)
            self.files = files

    def process(self, event):
        self.files.append(event.src_path)

    def on_created(self, event):
        self.process(event)

    def clear(self):
        self.files = []

    def __iter__(self):
        return self

    def next(self):
        if len(self.files) > 0:
            return self.files.pop(0)
        else:
            raise StopIteration()


class Fast5FileSet(object):

	def __init__(self, fileset, group=0):
		if isinstance(fileset, list):
			self.fileset = fileset
		elif isinstance(fileset, str):
			self.fileset = [fileset]
		self.set_type = None
		self.num_files_in_set = None
		self.group = group
		self._extract_fast5_files()

	def get_num_files(self):
		"""
		Return the number of files in the FAST5 set.
		"""
		if self.num_files_in_set is None and self.set_type == FAST5SET_TARBALL:
			self.num_files_in_set = len(self.files)
		return self.num_files_in_set

	def __iter__(self):
		return self

	def next(self):
		try:
			return Fast5File(self.files.next(), self.group)
		except Exception as e:
			# cleanup our mess
			if self.set_type == FAST5SET_TARBALL:
				shutil.rmtree(PORETOOLS_TMPDIR)
			raise StopIteration

	def _extract_fast5_files(self):

		# return as-is if list of files
		if len(self.fileset) > 1:
			self.files = iter(self.fileset)
			self.num_files_in_set = len(self.fileset)
			self.set_type = FAST5SET_FILELIST
		elif len(self.fileset) == 1:
			# e.g. ['/path/to/dir'] or ['/path/to/file']
			f = self.fileset[0]
			# is it a directory?
			if os.path.isdir(f):
				# Update (2/3/17) to account for new sub-directory
				# output from MinKNOW v1.4 release.
				files = [os.path.join(dirpath + os.path.sep + fast5file) \
								for dirpath, dirname, files in os.walk(f) \
									for fast5file in files]
				#pattern = f + '/' + '*.fast5'
				#files = glob.glob(pattern)
				self.files = iter(files)
				self.num_files_in_set = len(files)
				self.set_type = FAST5SET_DIRECTORY
				if not len(files):
					logger.warning("Directory is empty!")

			# is it a tarball?
			elif tarfile.is_tarfile(f):
				if os.path.isdir(PORETOOLS_TMPDIR):
					shutil.rmtree(PORETOOLS_TMPDIR)
				os.mkdir(PORETOOLS_TMPDIR)

				self.files = TarballFileIterator(f)
				# set to None to delay initialisation
				self.num_files_in_set = None
				self.set_type = FAST5SET_TARBALL

			# just a single FAST5 file.
			else:
				self.files = iter([f])
				self.num_files_in_set = 1
				self.set_type = FAST5SET_SINGLEFILE
		else:
			logger.error("Directory %s could not be opened. Exiting.\n" % dir)
			sys.exit()

class TarballFileIterator:
	def _fast5_filename_filter(self, filename):
		return os.path.basename(filename).endswith('.fast5') and not os.path.basename(filename).startswith('.')

	def __init__(self, tarball):
		self._tarball = tarball
		self._tarfile = tarfile.open(tarball)

	def __del__(self):
		self._tarfile.close()

	def __iter__(self):
		return self

	def next(self):
		while True:
			tarinfo = self._tarfile.next()
			if tarinfo is None:
				raise StopIteration
			elif self._fast5_filename_filter(tarinfo.name):
				break
		self._tarfile.extract(tarinfo, path=PORETOOLS_TMPDIR)
		return os.path.join(PORETOOLS_TMPDIR, tarinfo.name)

	def __len__(self):
		with tarfile.open(self._tarball) as tar:
			return len(tar.getnames())


class Fast5File(object):

	def __init__(self, filename, group=0):
		self.filename = filename
		self.group = group
		self.is_open = self.open()
		if self.is_open:
			self.version = self.guess_version()
		else:
			self.version = 'closed'

		self.fastas = {}
		self.fastqs = {}
		
		# pre-load the FASTQ data
		#self._extract_fastqs_from_fast5()

		# booleans for lazy loading (speed)
		self.have_fastqs = False
		self.have_fastas = False
		self.have_templates = False
		self.have_complements = False
		self.have_pre_basecalled = False
		self.have_metadata = False


	def __del__(self):
		self.close()

	####################################################################
	# Public API methods
	####################################################################

	def open(self):
		"""
		Open an ONT Fast5 file, assuming HDF5 format
		"""
		try:
			self.hdf5file = h5py.File(self.filename, 'r')
			return True
		except Exception, e:
			logger.warning("Cannot open file: %s. Perhaps it is corrupt? Moving on.\n" % self.filename)
			return False

	def guess_version(self):
		"""
		Try and guess the location of template/complement blocks
		"""
		try:
			self.hdf5file["/Analyses/Basecall_2D_%03d/BaseCalled_template" % (self.group)]
			return 'classic'
		except KeyError:
			pass

		try:
			self.hdf5file["/Analyses/Basecall_1D_%03d/BaseCalled_template" % (self.group)]
			return 'metrichor1.16'
		except KeyError:
			pass

		# less likely
                try:
                        self.hdf5file["/Analyses/Basecall_RNN_1D_%03d/BaseCalled_template" % (self.group)]
                        return 'r9rnn'
                except KeyError:
                        pass

		return 'prebasecalled'
			
	def close(self):
		"""
		Close an open an ONT Fast5 file, assuming HDF5 format
		"""
		if self.is_open:
			self.hdf5file.close()
			self.is_open = False

	def has_2D(self):
		"""
		Return TRUE if the FAST5 has a 2D base-called sequence.
		Return FALSE otherwise.
		"""
		if self.have_fastas is False:
			self._extract_fastas_from_fast5()
			self.have_fastas = True

		if self.fastas.get('twodirections') is not None:
			return True
		return False

	def get_fastqs(self, choice):
		"""
		Return the set of base called sequences in the FAST5
		in FASTQ format.
		"""
		if self.have_fastqs is False:
			self._extract_fastqs_from_fast5()
			self.have_fastqs = True

		fqs = []
		if choice == "all":
			for fastq in self.fastqs:
				fqs.append(self.fastqs[fastq])
		elif choice == "fwd":
				fqs.append(self.fastqs.get('template'))
		elif choice == "rev":
				fqs.append(self.fastqs.get('complement'))
		elif choice == "2D":
				fqs.append(self.fastqs.get('twodirections'))
		elif choice == "fwd,rev":
				fqs.append(self.fastqs.get('template'))
				fqs.append(self.fastqs.get('complement'))
		elif choice == "best":
				fqs.append(self.fastqs.get(self.get_best_type()))

		return fqs


	def get_fastas(self, choice):
		"""
		Return the set of base called sequences in the FAST5
		in FASTQ format.
		"""
		if self.have_fastas is False:
			self._extract_fastas_from_fast5()
			self.have_fastas = True

		fas = []
		if choice == "all":
			for fasta in self.fastas:
				fas.append(self.fastas[fasta])
		elif choice == "fwd":
				fas.append(self.fastas.get('template'))
		elif choice == "rev":
				fas.append(self.fastas.get('complement'))
		elif choice == "2D":
				fas.append(self.fastas.get('twodirections'))
		elif choice == "fwd,rev":
				fas.append(self.fastas.get('template'))
				fas.append(self.fastas.get('complement'))
		elif choice == "best":
				if self.have_fastqs is False:
					self._extract_fastqs_from_fast5()
					self.have_fastqs = True
				fas.append(self.fastas.get(self.get_best_type()))

		return fas

	def get_fastas_dict(self):
                """
                Return the set of base called sequences in the FAST5
                in FASTQ format.
                """
                if self.have_fastas is False:
                        self._extract_fastas_from_fast5()
                        self.have_fastas = True

		return self.fastas

	def get_fastq(self):
		"""
		Return the base called sequence in the FAST5
		in FASTQ format. Try 2D then template, then complement.
		If all fail, return None
		"""
		if self.have_fastqs is False:
			self._extract_fastqs_from_fast5()
			self.have_fastqs = True

		if not self.fastqs:
			return None
		elif self.fastqs.get('twodirections') is not None:
			return self.fastqs.get('twodirections')
		elif self.fastqs.get('template') is not None:
			return self.fastqs.get('template')
		elif self.fastqs.get('complement') is not None:
			return self.fastqs.get('complement')


	def get_fasta(self):
		"""
		Return the base called sequence in the FAST5
		in FASTA format. Try 2D then template, then complement.
		If all fail, return None
		"""
		if not self.fastas:
			return None
		elif self.fastas.get('twodirections') is not None:
			return self.fastas.get('twodirections')
		elif self.fastas.get('template') is not None:
			return self.fastas.get('template')
		elif self.fastas.get('complement') is not None:
			return self.fastas.get('complement')

	def get_template_events(self):
		"""
		Return the table of event data for the template strand
		"""
		if self.have_templates is False:
			self._extract_template_events()
			self.have_templates = True

		return self.template_events

	def get_complement_events(self):
		"""
		Return the table of event data for the complement strand
		"""
		if self.have_complements is False:
			self._extract_complement_events()
			self.have_complements = True
		
		return self.complement_events

	def get_pre_basecalled_events(self):
		"""
		Return the table of pre-basecalled events
		"""
		if self.have_pre_basecalled is False:
			self._extract_pre_basecalled_events()
			self.have_pre_basecalled = True

		return self.pre_basecalled_events		

	####################################################################
	# Flowcell Metadata methods
	####################################################################

	def get_exp_start_time(self):
		"""
		Return the starting time at which signals were collected
		for the given read.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			if self.keyinfo['tracking_id'].attrs['exp_start_time'].endswith('Z'):
				# MinKNOW >= 1.4 ISO format and UTC time
				dt = dateutil.parser.parse(self.keyinfo['tracking_id'].attrs['exp_start_time'])
				timestamp = int(time.mktime(dt.timetuple()))
			else:
				# Unix time stamp from MinKNOW < 1.4
				timestamp = int(self.keyinfo['tracking_id'].attrs['exp_start_time'])
			return timestamp
		except KeyError, e:
			return None

	def get_channel_number(self):
		"""
		Return the channel (pore) number at which signals were collected
		for the given read.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return int(self.keyinfo['channel_id'].attrs['channel_number'])
		except:
			pass

		try:
			return int(self.keyinfo['read_id'].attrs['channel_number'])
		except:
			return None

	def find_read_number_block_link(self):
		"""
		Old-style FAST5/HDF5 structure:
		Inside /Analyses/Basecall_XXXX there is an 'InputEvents'
		link that points to the location of the Read in the HDF5 file.

		Return the Read's node if found, or None if not found.
		"""
		if self.version == 'classic':
			path = "/Analyses/Basecall_2D_000"
		else:
			path = "/Analyses/Basecall_1D_000"

		basecall = self.hdf5file[path]
		path = basecall.get('InputEvents', getlink=True)
		if path is None:
			return None

		# the soft link target seems broken?
		newpath = "/" + "/".join(path.path.split("/")[:-1])

		node = self.hdf5file[newpath]

		return node

	def hdf_internal_error(self,reason):
		"""Report an error and exit in case of an invalid
(or unknown) HDF5 structure. Hurrah for ONT!"""
		msg = """poretools internal error in file '%s':
%s
Please report this error (with the offending file) to:
    https://github.com/arq5x/poretools/issues""" % (self.filename, reason)
		sys.exit(msg)

        def find_read_number_block_fixed_raw(self):
		"""
		New-style FAST5/HDF5 structure:
		There is a fixed 'Raw/Reads' node with only one 'read_NNN' item
		inside it (no more 'InputEvents' link).

		Return the Read's node if found, or None if not found.
		"""
		raw_reads = self.hdf5file.get('Raw/Reads')
		if raw_reads is None:
			return None

		reads = raw_reads.keys()
		if len(reads)==0:
			self.hdf_internal_error("Raw/Reads group does not contain any items")
		if len(reads)>1:
			# This should not happen, based on information from ONT developers.
			self.hdf_internal_error("Raw/Reads group contains more than one item")
		path = 'Raw/Reads/%s' % ( reads[0] )
		node = self.hdf5file.get(path)
		if node is None:
			self.hdf_internal_error("Failed to get HDF5 item '%s'"% (path))
		return node

        def find_read_number_block(self):
		"""Returns the node of the 'Read_NNN' information, or None if not
		found"""
		node = self.find_read_number_block_link()
		if node is not None:
			return node

		node = self.find_read_number_block_fixed_raw()
		if node is not None:
			return node

		# Couldn't find the node, bail out.
		self.hdf_internal_error("unknown HDF5 structure: can't find read block item")

	def find_event_timing_block(self):
		path = fastq_paths[self.version]['template'] % (self.group)
		try:
			node = self.hdf5file[path]
			path = node.get('Events')
#, getlink=True)
			return path
		except Exception:
			return None

	def get_read_number(self):
		"""
		Return the read number for the pore representing the given read.
		"""
		node = self.find_read_number_block()
		if node:
			try:
				return int(node.attrs['read_number'])
			except:
				return None
		return None

	def get_start_mux(self):
		"""
		Return the mux (multiplexer) setting for this read: identify the pore with this and get_channel_number()
		"""
		node = self.find_read_number_block()
		if node:
			try:
				return int(node.attrs['start_mux'])
			except:
				return None
		return None

	def get_duration(self):
		# poretools returns in seconds not samples

		node = self.find_read_number_block_fixed_raw()
		if node:
			try:
				return int(node.attrs['duration']) / self.get_sample_frequency()
			except Exception, e:
				logger.error(str(e))
				pass

		node = self.find_event_timing_block()
		if node:
			#NOTE: 'duration' in the HDF is a float-point number,
			#      and can be less than one - which will return 0.
			#TODO: consider supporing floating-point, or at least
			#      rounding values instead of truncating to int.
			return int(node.attrs['duration'])
		return None

	def get_start_time(self):
		# poretools returns a unix timestamp not samples

		exp_start_time	= self.get_exp_start_time()

		# new raw files
		node = self.find_read_number_block_fixed_raw()
		if node:
			try:
				frequency = int(self.get_sample_frequency())
				return int(exp_start_time) + int(node.attrs['start_time'] / frequency)
			except Exception, e:
				logger.error(str(e))
				pass
 		
		node = self.find_event_timing_block()
		if node:
			return int(exp_start_time) + int(node.attrs['start_time'])
	
		return None

	def get_end_time(self):
		exp_start_time	= self.get_exp_start_time()
		start_time = self.get_start_time()
		duration = self.get_duration()

		# 'duration' can be zero and still valid
		# (if the duration of the template was less than 1 second).
		# Check for None instead of False.
		if start_time and (duration is not None):
			return start_time + duration
		else:
			return None

	def get_version_name(self):
		"""
		Return the flow cell version name.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['context_tags'].attrs['version_name']
		except:
			return None

	def get_minknow_version(self):
		"""
		Return the flow cell version name.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['context_tags'].attrs['verssion']
		except:
			return None

	def get_run_id(self):
		"""
		Return the run id.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['run_id']
		except:
			return None

	def get_heatsink_temp(self):
		"""
		Return the heatsink temperature.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['heatsink_temp']
		except:
			return None

	def get_asic_temp(self):
		"""
		Return the ASIC temperature.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['asic_temp']
		except:
			return None

	def get_flowcell_id(self):
		"""
		Return the flowcell_id.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['flowcell_id']
		except:
			pass

		try:
			return self.keyinfo['tracking_id'].attrs['flow_cell_id']
		except:
			return None

	def get_host_name(self):
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['hostname']
		except:
			return None

	def get_run_purpose(self):
		"""
		Return the exp_script_purpose.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['exp_script_purpose']
		except:
			return None

	def get_asic_id(self):
		"""
		Return the flowcell's ASIC id.
		"""
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['asic_id']
		except:
			return None

		if self.have_metadata is False:
			self._get_metadata()
			self.have_metadata = True

        def get_host_name(self):
                """
                Return the MinKNOW host computer name.
                """
                if self.have_metadata is False:
                        self._get_metadata()
                        self.have_metadata = True

                try:
                        return self.keyinfo['tracking_id'].attrs['hostname']
                except:
                        return None

                if self.have_metadata is False:
                        self._get_metadata()
                        self.have_metadata = True

	def get_device_id(self):
		"""
		Return the flowcell's device id.
		"""

                if self.have_metadata is False:
                        self._get_metadata()
                        self.have_metadata = True

		try:
			return self.keyinfo['tracking_id'].attrs['device_id']
		except:
			return None

	def get_sample_name(self):
		"""
		Return the user supplied sample name
		"""

                if self.have_metadata is False:
                        self._get_metadata()
                        self.have_metadata = True

		try:
			return self.keyinfo['context_tags'].attrs['user_filename_input']
		except Exception, e:
			return None

	def get_sample_frequency(self):
		"""
		Return the user supplied sample name
		"""

                if self.have_metadata is False:
                        self._get_metadata()
                        self.have_metadata = True

		try:
			return int(self.keyinfo['context_tags'].attrs['sample_frequency'])
		except Exception, e:
			return None

	def get_script_name(self):
		if self.have_metadata is False:
			self._get_metadata()
			self.have_metdata = True
		try:
			return self.keyinfo['tracking_id'].attrs['exp_script_name']
		except Exception, e:
			return None

	def get_template_events_count(self):
		"""
		Pull out the event count for the template strand
		"""
		try:
			table = self.hdf5file[fastq_paths[self.version]['template'] % self.group]
			return len(table['Events'][()])
		except Exception, e:
			return 0

	def get_complement_events_count(self):
		"""
		Pull out the event count for the complementary strand
		"""
		try:
			table = self.hdf5file[fastq_paths[self.version]['complement'] % self.group]
			return len(table['Events'][()])
		except Exception, e:
			return 0

	def is_high_quality(self):
		if self.get_complement_events_count() >= \
		   self.get_template_events_count():
			return True
		else:
			return False

	def get_best_type(self):
		"""
		Returns the type with the anticipated highest quality:
		'twodirections', 'template', 'complement' or None.
		"""
		try:
			if 'twodirections' in self.fastqs:
				return 'twodirections'
			fwd = 'template' in self.fastqs
			rev = 'complement' in self.fastqs
			if fwd and not rev:
				return 'template'
			elif rev and not fwd:
				return 'complement'
			else:
				fwd_err_rate = self.fastqs['template'].est_error_rate()
				rev_err_rate = self.fastqs['complement'].est_error_rate()
				if fwd_err_rate <= rev_err_rate:
					return 'template'
				else:
					return 'complement'
		except Exception, e:
			return None

	####################################################################
	# Private API methods
	####################################################################

	def _extract_fastqs_from_fast5(self):
		"""
		Return the sequence in the FAST5 file in FASTQ format
		"""
		for id, h5path in fastq_paths[self.version].iteritems(): 
			try:
				table = self.hdf5file[h5path % self.group]
				fq = formats.Fastq(table['Fastq'][()])
				fq.name += " " + self.filename
				self.fastqs[id] = fq
			except Exception, e:
				pass

	def _extract_fastas_from_fast5(self):
		"""
		Return the sequence in the FAST5 file in FASTA format
		"""
		for id, h5path in fastq_paths[self.version].iteritems(): 
			try:
				table = self.hdf5file[h5path % self.group]
				fa = formats.Fasta(table['Fastq'][()])
				fa.name += " " + self.filename
				self.fastas[id] = fa
			except Exception, e:
				pass

	def _extract_template_events(self):
		"""
		Pull out the event information for the template strand
		"""
		try:
			table = self.hdf5file[fastq_paths[self.version]['template'] % self.group]
			self.template_events = [Event(x) for x in table['Events'][()]]
		except Exception, e:
			self.template_events = []

	def _extract_complement_events(self):
		"""
		Pull out the event information for the complementary strand
		"""
		try:
			table = self.hdf5file[fastq_paths[self.version]['complement'] % self.group]
			self.complement_events = [Event(x) for x in table['Events'][()]]
		except Exception, e:
			self.complement_events = []

	def _extract_pre_basecalled_events(self):
		"""
		Pull out the pre-basecalled event information 
		"""
		# try:
		table = self.hdf5file[fastq_paths[self.version]['pre_basecalled']]
		events = []
		for read in table:
			events.extend(table[read]["Events"][()])
		self.pre_basecalled_events = [Event(x) for x in events]
		# except Exception, e:
			# self.pre_basecalled_events = []			

	def _get_metadata(self):
		try:
			self.keyinfo = self.hdf5file['/UniqueGlobalKey']
		except Exception, e:
			try:
				self.keyinfo = self.hdf5file['/Key']
			except Exception, e:
				self.keyinfo = None
				logger.warning("Cannot find keyinfo. Exiting.\n")


================================================
FILE: poretools/__init__.py
================================================
import os
import sys
import scripts
from Fast5File import *
from version import __version__


================================================
FILE: poretools/combine.py
================================================
import tarfile
import sys
import Fast5File

#logging
import logging
logger = logging.getLogger('poretools')


def run(parser, args):
	
	if args.tar_filename.endswith('.tar'):
		tar = tarfile.open(args.tar_filename, mode='w')
	elif args.tar_filename.endswith('.gz'):
		tar = tarfile.open(args.tar_filename, mode='w:gz')
	elif args.tar_filename.endswith('.bz2'):
		tar = tarfile.open(args.tar_filename, mode='w:bz2')
	else:
		logger.error("Unrecognized FAST5 archive extension. Exiting.\n")
		sys.exit()

	file_count = 0
	for fast5 in Fast5File.Fast5FileSet(args.files):
		tar.add(fast5.filename)
		fast5.close()
		file_count += 1
	tar.close()

	logger.info("%s successfully created from %d FAST5 files.\n" % \
		(args.tar_filename, file_count))


================================================
FILE: poretools/events.py
================================================
import Fast5File

def run(parser, args):

	# print header.
	keys = ['file', 'strand', 'mean', 'start', 'stdv', \
			'length', 'model_state', 'model_level', 'move', \
			'p_model_state', 'mp_model_state', 'p_mp_model_state', \
			'p_A', 'p_C', 'p_G', 'p_T', 'raw_index']
	print "\t".join(keys)

	if args.pre_basecalled:
		for fast5 in Fast5File.Fast5FileSet(args.files):
			for event in fast5.get_pre_basecalled_events(): 
				print '\t'.join([fast5.filename, 'pre_basecalled', str(event)])
	else:
		for fast5 in Fast5File.Fast5FileSet(args.files):
			for event in fast5.get_template_events():
				print '\t'.join([fast5.filename, 'template', str(event)]) 
			for event in fast5.get_complement_events():
				print '\t'.join([fast5.filename, 'complement', str(event)]) 

		fast5.close()



================================================
FILE: poretools/fasta.py
================================================
import Fast5File
import sys

def run(parser, args):

	for fast5 in Fast5File.Fast5FileSet(args.files, args.group):

		if args.start_time or args.end_time:
			read_start_time = fast5.get_start_time()
			read_end_time = fast5.get_end_time()
			if args.start_time and args.start_time > read_start_time:
				fast5.close()
				continue
			if args.end_time and args.end_time < read_end_time:
				fast5.close()
				continue

		fas = fast5.get_fastas(args.type)
		
		# high quality 2D: means there are more nanopore events on the 
		# complement strand than on the template strand. We also
		# require there to be a 2D base-called sequence from Metrichor.
		if args.high_quality:
			if (fast5.get_complement_events_count() <= \
			   fast5.get_template_events_count()) or not fast5.has_2D():
				fast5.close()
				continue

		# norem quality 2D : means there are less (or equal) nanopore 
		# events on the complement strand than on the template strand. 
		# We also require there to be a 2D base-called sequence from Metrichor.
		if args.normal_quality:
			if (fast5.get_complement_events_count() > \
			   fast5.get_template_events_count()) or not fast5.has_2D():
				fast5.close()
				continue

		for fa in fas:
			if fa is None or \
			len(fa.seq) < args.min_length or \
			(len(fa.seq) > args.max_length and \
			args.max_length > 0):			
				continue			

			print fa

		fast5.close()



================================================
FILE: poretools/fastq.py
================================================
import Fast5File
import sys

def run(parser, args):
	
	for fast5 in Fast5File.Fast5FileSet(args.files, args.group):

		if args.start_time or args.end_time:
			read_start_time = fast5.get_start_time()
			read_end_time = fast5.get_end_time()
			if args.start_time and args.start_time > read_start_time:
				fast5.close()
				continue
			if args.end_time and args.end_time < read_end_time:
				fast5.close()
				continue

		fas = fast5.get_fastqs(args.type)

		# high quality 2D: means there are more nanopore events on the 
		# complement strand than on the template strand. We also
		# require there to be a 2D base-called sequence from Metrichor.
		if args.high_quality:
			if (fast5.get_complement_events_count() <= \
			   fast5.get_template_events_count()) or not fast5.has_2D():
				fast5.close()
				continue

		# norem quality 2D : means there are less (or equal) nanopore 
		# events on the complement strand than on the template strand. 
		# We also require there to be a 2D base-called sequence from Metrichor.
		if args.normal_quality:
			if (fast5.get_complement_events_count() > \
			   fast5.get_template_events_count()) or not fast5.has_2D():
				fast5.close()
				continue

		for fa in fas:
			if fa is None or \
			len(fa.seq) < args.min_length or \
			(len(fa.seq) > args.max_length and \
			args.max_length > 0):			
				continue

			print fa

		fast5.close()



================================================
FILE: poretools/formats.py
================================================
class Fastq(object):
	def __init__(self, s):
		self.s = s
		self.parse()

	def parse(self):
		(self.name, self.seq, self.sep, self.qual) = self.s.strip().split('\n')

	def __repr__(self):
		return '\n'.join([self.name, self.seq, self.sep, self.qual])

	def est_error_rate(self):
		"""
		Returns an error rate estimate using the Phred quality scores.
		"""
		try:
			error_count = 0.0
			for score in self.qual:
				phred = ord(score) - 33
				error_count += 10.0 ** (-phred / 10.0)
			return error_count / len(self.qual)
		except Exception, e:
			return 0.0



class Fasta(object):
	def __init__(self, s):
		self.s = s
		self.parse()

	def parse(self):
		(self.name, self.seq, self.sep, self.qual) = self.s.strip().split('\n')
		self.name = self.name.lstrip('@')

	def __repr__(self):
		return '\n'.join(['>'+self.name, self.seq])

================================================
FILE: poretools/hist.py
================================================
import sys
import time

import matplotlib
#matplotlib.use('Agg') # Must be called before any other matplotlib calls
from matplotlib import pyplot as plt

import seaborn as sns
import Fast5File

import logging
logger = logging.getLogger('poretools')
logger.setLevel(logging.INFO)

def plot_hist(sizes, args):
    """
    plot a histogram of the read sizes
    """
    sizes = [s for s in sizes if args.min_length < s < args.max_length]

    if args.theme_bw:
        sns.set_style("whitegrid")
    plt.hist(sizes, args.num_bins)
    plt.xlabel('sizes')

    if args.saveas is not None:
        plt.savefig(args.saveas)
    else:
        plt.show()

def run(parser, args):
    sizes = []
    files_processed = 0

    for fast5 in Fast5File.Fast5FileSet(args.files):
        fq = fast5.get_fastq()
        if fq is not None:
            sizes.append(len(fq.seq))
        files_processed += 1
        if files_processed % 100 == 0:
            logger.info("%d files processed." % files_processed)
        fast5.close()
    plot_hist(sizes, args)



================================================
FILE: poretools/index.py
================================================
import Fast5File
import datetime

############
#
#	index
#
#   A tool to extract
#	all info needed to 
#	identify a pile of 
#	unsorted reads from 
#	multiple MinION
#	sequencing 
#	experiments.
#
############

def run(parser, args):

	print "source_filename\ttemplate_fwd_length\tcomplement_rev_length\t2d_length\tasic_id\tasic_temp\theatsink_temp\tchannel\texp_start_time\texp_start_time_string_date\texp_start_time_string_time\tstart_time\tstart_time_string_date\tstart_time_string_time\tduration\tfast5_version"

	for fast5 in Fast5File.Fast5FileSet(args.files):
		
		
		# run and flowcell parameters
		asic_temp  = fast5.get_asic_temp()
		asic_id = fast5.get_asic_id()
		heatsink_temp = fast5.get_heatsink_temp()
		channel_number = fast5.get_channel_number()
		
		# try and get timing info
		try:
			start_time = fast5.get_start_time()
			start_time_string = datetime.datetime.fromtimestamp(float(start_time)).strftime("%Y-%b-%d (%a)\t%H:%M:%S")
			exp_start_time = fast5.get_exp_start_time()
			exp_start_time_string = datetime.datetime.fromtimestamp(float(exp_start_time)).strftime("%Y-%b-%d (%a)\t%H:%M:%S")
			duration = fast5.get_duration()
		except KeyError:	
			start_time = "Not found"
			start_time_string = "NA\tNA"
			exp_start_time = "Not found"
			exp_start_time_string = "NA\tNA"
			duration = "Not found"
		
		# sequence file info
		fast5_version = fast5.guess_version()
		
		# read info
		fastq_reads = fast5.get_fastqs('all')
		length_template = None
		length_complement = None
		length_2d = None
		if (len(fastq_reads) > 0):
			length_template = len(fastq_reads[0].seq)
		if (len(fastq_reads) > 2):
			length_complement = len(fastq_reads[1].seq)
			length_2d = len(fastq_reads[2].seq)

		print "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (
			fast5.filename,
			length_template,
			length_complement,
			length_2d,		
			asic_id, asic_temp, heatsink_temp,channel_number,exp_start_time,exp_start_time_string,start_time,start_time_string,duration,fast5_version)

		fast5.close()


================================================
FILE: poretools/ipynb/test_run_report.ipynb
================================================
{
 "metadata": {
  "name": "",
  "signature": "sha256:d0b818846b182639011099ca56fd583aa186cae4284de49607ba34231dc100f2"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This IPython notebook file demonstrates some of the functionality available in __poretools__, and an example run report for a recent R7 chemistry nanopore run. "
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Some of the examples call out to R for plotting, so to make this work in this notebook we need to load the ``rpy2.ipython`` module."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%load_ext rpy2.ipython"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 53
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "__poretools__ can run either on an individual FAST5 file, a directory containing FAST5 files, or a tar archive of FAST5 files. Here we set up a `$directory` variable for use for the rest of the tutorial. You could change this and run the same commands on your data."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "directory='/mnt/borage/nick/nanopore/data/Flowcell6/downloads'"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 18
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!find $directory -maxdepth 1 -name \"*.fast5\" | wc -l"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "60196\r\n"
       ]
      }
     ],
     "prompt_number": 65
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "There are 60,196 FAST5 files in the directory."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "__poretools__ has a number of different command line options. Running __poretools__ with no parameters gives us a brief list (and complies with [Torsten's first rule](http://www.gigasciencejournal.com/content/2/1/15))"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "usage: poretools [-h] [-v]\r\n",
        "                 \r\n",
        "                 {combine,fastq,fasta,stats,hist,events,readstats,tabular,nucdist,qualdist,winner,squiggle,times,yield_plot}\r\n",
        "                 ...\r\n",
        "poretools: error: too few arguments\r\n"
       ]
      }
     ],
     "prompt_number": 21
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We can get more information if we run __poretools__ with the -h (help) option."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools -h"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "usage: poretools [-h] [-v]\r\n",
        "                 \r\n",
        "                 {combine,fastq,fasta,stats,hist,events,readstats,tabular,nucdist,qualdist,winner,squiggle,times,yield_plot}\r\n",
        "                 ...\r\n",
        "\r\n",
        "optional arguments:\r\n",
        "  -h, --help            show this help message and exit\r\n",
        "  -v, --version         Installed poretools version\r\n",
        "\r\n",
        "[sub-commands]:\r\n",
        "  {combine,fastq,fasta,stats,hist,events,readstats,tabular,nucdist,qualdist,winner,squiggle,times,yield_plot}\r\n",
        "    combine             Combine a set of FAST5 files in a TAR achive\r\n",
        "    fastq               Extract FASTQ sequences from a set of FAST5 files\r\n",
        "    fasta               Extract FASTA sequences from a set of FAST5 files\r\n",
        "    stats               Get read size stats for a set of FAST5 files\r\n",
        "    hist                Plot read size histogram for a set of FAST5 files\r\n",
        "    events              Extract each nanopore event for each read.\r\n",
        "    readstats           Extract signal information for each read over time.\r\n",
        "    tabular             Extract the lengths and name/seq/quals from a set of\r\n",
        "                        FAST5 files in TAB delimited format\r\n",
        "    nucdist             Get the nucl. composition of a set of FAST5 files\r\n",
        "    qualdist            Get the qual score composition of a set of FAST5 files\r\n",
        "    winner              Get the longest read from a set of FAST5 files\r\n",
        "    squiggle            Plot the observed signals for FAST5 reads.\r\n",
        "    times               Return the start times from a set of FAST5 files in\r\n",
        "                        tabular format\r\n",
        "    yield_plot          Plot the yield over time for a set of FAST5 files\r\n"
       ]
      }
     ],
     "prompt_number": 22
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's start with a simple one, the ``stats`` command, this will give us some basic statistics about our reads.\n",
      "\n",
      "The ``-q`` option stops ``poretools`` outputting any warning messages."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools stats -q $directory"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "total reads\t104969\r\n",
        "total base pairs\t550200969\r\n",
        "mean\t5241.56\r\n",
        "median\t4616\r\n"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "min\t5\r\n",
        "max\t154417\r\n"
       ]
      }
     ],
     "prompt_number": 68
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "How do we have 104,969 reads from 60,196 FAST5 files? That's because forward, reverse and two-directional reads are all counted separately."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools stats -q --type fwd $directory"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "total reads\t53914\r\n",
        "total base pairs\t290880019\r\n",
        "mean\t5395.26\r\n",
        "median\t4441\r\n",
        "min\t5\r\n",
        "max\t154417\r\n"
       ]
      }
     ],
     "prompt_number": 69
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We have 53,914 forward reads in our total dataset."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools stats -q --type rev $directory"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "total reads\t29622\r\n",
        "total base pairs\t124718901\r\n",
        "mean\t4210.35\r\n",
        "median\t3765\r\n",
        "min\t5\r\n",
        "max\t44835\r\n"
       ]
      }
     ],
     "prompt_number": 71
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools stats -q --type 2D $directory"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "total reads\t21433\r\n",
        "total base pairs\t134602049\r\n",
        "mean\t6280.13\r\n",
        "median\t6020\r\n",
        "min\t211\r\n",
        "max\t38598\r\n"
       ]
      }
     ],
     "prompt_number": 70
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We have 21,433 two-direction reads, which is about 40% of the reads which have been base-called and about 72% of the reads that have a detectable complement strand."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools readstats -q $directory > readstats.txt"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 73
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!wc -l readstats.txt"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "``readstats`` gives you a line per every FAST5 file in your dataset. The columns are:\n",
      "*   start_time (represented as a UNIX timestamp, e.g. seconds since the UNIX epoch)\n",
      "*   pore number\n",
      "*   read number (not working ATM, the format changed)\n",
      "*   length of forward read\n",
      "*   length of reverse read"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!head -10 readstats.txt"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "1404984747\t491\tNone\t301\t0\r\n",
        "1405005921\t325\tNone\t299\t0\r\n",
        "None\t410\tNone\t0\t0\r\n",
        "1404940637\t415\tNone\t5271\t5113\r\n",
        "1405002720\t222\tNone\t3064\t0\r\n",
        "1404959466\t209\tNone\t5901\t5634\r\n",
        "1404949019\t12\tNone\t4524\t3576\r\n",
        "1404930734\t470\tNone\t345\t0\r\n",
        "1404936756\t491\tNone\t310\t0\r\n",
        "1404947432\t109\tNone\t697\t0\r\n"
       ]
      }
     ],
     "prompt_number": 75
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "One useful plot you can easily do with the output of read stats is to plot the number of events in forward reads against reverse reads. Ideally every read would have a similar number, which would indicate the hairpin is correctly attached and the strand translocation rate is controlled by the enzyme."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%R stats=read.table(\"readstats.txt\", sep=\"\\t\")\n",
      "%R stats=subset(stats, V4 < 20000 & V5 < 20000)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<pre>\n",
        "&ltclass 'pandas.core.frame.DataFrame'&gt\n",
        "Int64Index: 59048 entries, 0 to 59047\n",
        "Data columns (total 5 columns):\n",
        "V1    59048  non-null values\n",
        "V2    59048  non-null values\n",
        "V3    59048  non-null values\n",
        "V4    59048  non-null values\n",
        "V5    59048  non-null values\n",
        "dtypes: int32(2), object(3)\n",
        "</pre>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 79,
       "text": [
        "<class 'pandas.core.frame.DataFrame'>\n",
        "Int64Index: 59048 entries, 0 to 59047\n",
        "Data columns (total 5 columns):\n",
        "V1    59048  non-null values\n",
        "V2    59048  non-null values\n",
        "V3    59048  non-null values\n",
        "V4    59048  non-null values\n",
        "V5    59048  non-null values\n",
        "dtypes: int32(2), object(3)"
       ]
      }
     ],
     "prompt_number": 79
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%R smoothScatter(stats$V4,stats$V5)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\ntCAlr0cjd9AAAJBpGlniAACATIMOGgAAUgo6aAAASCnooAEAIKWggwYAgJSCDhoAAFIKOmgAAEgp\njdlBP/fcc+985ztnz5794Q9/eGRkZLKbEzsrV67MeaxZs6acqHwI5okZ5f3vf/+ePXvEfyM+hKw/\nmcDTmMrvyVNPPfWOd7xj2rRpy5cv37VrVzkxA6+H23CMj4+ffvrpvb29Bw4cWLVq1T/8wz9Mdoti\n57TTTvvxj3/88ssvv/zyy4cPH3Y1D8E8MYs89dRTf/qnf+o4zgsvvFBOifgQMv1k6NNwp/B7cujQ\noa6uroceeuj111//67/+67e97W1uRl6PBuygn3rqqbe85S3l423bti1evHhy2xM3Y2NjbW1tExMT\ncqLyIZgnZpHPfvazH//4xzs7O0WXFPEhZPrJ0Kcxld+Tb3/72+95z3vKx2NjY7lc7rXXXsvE69GA\nEse+ffuWLFlSPl6yZMkrr7ziNvR09v3793d0dFx55ZWLFi267rrrDh486GgegnnipNxIRD7xiU/c\nf//9s2fPFikRH0Kmnwx9GlP5PXn/+9//yCOPlI+feeaZhQsXzpo1KxOvRwN20P39/dOnTy8fz5gx\no1AoDA4OTm6TYuXYsWOnn376jTfe+NhjjzU3N19zzTWO5iGYJ07KjdSdiA+hwZ7MVH5Ppk+f/qY3\nvcl13UceeeS66677whe+kMvlMvF6pGJJvfoye/bsoaGh8vHAwEA+n+/q6prcJsXK+eef/4tf/KJ8\n/JWvfGXmzJn9/f3Kh2CemPxdxEHEh9BgT2aKvyevvvrqDTfcsH///r6+vmXLljkZeT0a0II+44wz\nhJf2hRdeWLhwYVNTA96mYOfOnTt27Cgft7a2lpeyVT4E88Tk7yIOIj6EBnsyU/k9GRsbe9/73vfW\nt7712WefLffOTlZejziE7cllfHx8/vz53/nOdwYHBy+//PK/+7u/m+wWxct//dd/zZo1a/v27f39\n/bfddtuqVatczUMwT8wuv/M7vyNHcUR5CA3wZOSnMZXfk29/+9tLly59WWJiYiITr0cDdtCu6+7c\nuXPp0qUnnXTShz70odHR0cluTryUSqWvfvWrixcvnjFjxpVXXnno0KFyuvIhmCdmFLlLciM/hKw/\nGflpTOX35C/+4i8ChumxY8fcLLweWLAfAABSSmZUJAAAmGqggwYAgJSCDhoAAFIKOmgAAEgp6KAB\nACCloIMGAICUgg4aAABSCjpoAABIKeigAQAgpaCDBgCAlIIOGgAAUgo6aAAASCnooAEAIKWggwYA\ngJSCDhoAAFIKOmgAAEgp6KABACCloIMGAICUgg4aTHWKxeJTTz21evXqgwcPTnZbAKgCHTRoEPL5\n/MTEhO3ZsbGx9773vZ/85CdffPHFZcuWPfTQQ47jfOYzn1m9erWcbcOGDTfffLP47549e7q6uurX\ndgDUoIMGU5q+vr7W1tYnn3zywgsv/O53v/upT33KcZz169f/6Ec/OnbsWDnPxMTEI488cs0115T/\nWywWP/KRj4yOjk5ao8GUAR00yB4TExM33njj7Nmz586d++lPf9pxnPe9733FYvF3f/d3T5w40dvb\n293d3dHR8Z73vOf//u//5LNvvPFG4MITJ04IW/j8889/5JFHHMdZuHDheeed9/DDD5fTn3766XJp\n5f/ed999p556avJ3DaYiLgBZ46GHHjrrrLNefvnln/3sZ21tbXv37nVdt7m5eXx8fP/+/a2trdu3\nbz927NiHPvShjRs3li8pn6UXHjp06JRTTvnDP/zDNWvWnDhxQlRx3333XXTRReXjP/uzP7vlllvK\nx3v37j3rrLN+/etfNzc3J3vTYCoCCxpkkvHx8aNHj77jHe84cODAaaedJtJPPvnkF198ccWKFR0d\nHXPnzn3jjTf4C0855ZRf/vKXS5cu3bFjx/z58zdt2lTOdvXVVz/99NNHjhxxXfd73/veunXrHMcp\nlUo33HDDP/7jP86YMSOxOwVTmfxkNwAAa6666qqBgYGNGzceOXLk4x//+G233SZO5fP5r33ta1u3\nbp05c2ZbW9v06dNrXnjyySfffPPNv/nNbz7ykY+sWrVq7dq1M2fOnDdv3oUXXvjwww+fe+65uVzu\n3e9+t+M4X/va1+bPn3/ZZZf19/cnfMtgaoIOGmSPl1566aKLLtqwYcP+/fuvvvrqWbNm3XTTTeVT\n3/nOd/7jP/7jBz/4wUknnfTP//zPjz32GH/h/v37Tz311Ouuu85xnBUrVpx55pm//e1vZ86c6TjO\ntdde+8ADDxw4cGDdunW5XM5xnP/8z/98/PHH586dWyqVisXi3LlzH3vsMaFNA1B3IHGA7LFly5Zr\nr732yJEjxWJxbGyso6OjnD40NPTqq692dXV1dHQcPXr0vvvuGxkZEVcNDQ3RC88555xvfetbQ0ND\nrus+9dRTr7/++uLFi8v5r7zyymefffab3/xmWd9wHOdLX/rS7t27f/GLX/zoRz9qamr6xS9+8Xu/\n93sJ3zuYWky2CA6ANYODg1dcccW0adNOOumkj33sY4VCwXXddevWTZ8+/eDBg6tXrz7ppJN+//d/\n/9FHH503b943v/lNcfbw4cOBCwuFwo033jh//vy2trZ3vetdTz/9tFzRVVddtXDhwlKpFGjAsWPH\n4CQECZBzXXey/0YAMMn09/ffeuut3/zmNye7IQBUAYkDAKetre2CCy6Y7FYAEAQWNAAApBRY0AAA\nkFLQQQMAQEpBBw0AACkFHTQAAKQUdNAAAJBS0EEDAEBKQQcNAAApBR00AACkFHTQAACQUtBBAwBA\nSkEHDQAAKQUdNAAApBR00AAAkFLQQQMAQEpBBw0AACkFHTQAAKSU/weBPucO8tW+JAAAAABJRU5E\nrkJggg==\n"
      }
     ],
     "prompt_number": 77
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!poretools winner -q --type 2D $directory > winner.fasta"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This will just use the header data to generate a squiggle plot:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "!head -1 winner.fasta | sed 's/>.* //' | xargs poretools squiggle --saveas png --num-facets 12"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 126
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "squiggle=!head -1 winner.fasta | sed 's/>.* //'\n",
      "squiggle=squiggle[0] + '.png'\n",
      "Image(squiggle)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAACfYAAAzkCAMAAAAgP32bAAADAFBMVEUAAAABAQECAgIDAwMEBAQF\nBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUWFhYXFxcY\nGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJycoKCgpKSkqKior\nKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+\nPj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tMTExNTU1OTk5PT09QUFBR\nUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2Nk\nZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3\nd3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKDg4OEhISFhYWGhoaHh4eIiIiJiYmK\nioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJyd\nnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+w\nsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLD\nw8PExMTFxcXGxsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW\n1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp\n6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8\n/Pz9/f3+/v7////isF19AAAACXBIWXMAAC4jAAAuIwF4pT92AAAgAElEQVR4nOydBZwVVfvHH5bu\nEhBFwURFBAMD9VVB7L+t2IndovJisCoCYqGigoUoKCiKCmK8KmJhgwiSSiOyIrHUUvf+zzN5Js7E\n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\nimL0ne2xL6SaFfu0R
Download .txt
gitextract_uu4w_ikh/

├── .gitignore
├── Dockerfile
├── LICENSE
├── MANIFEST.in
├── README.md
├── appveyor/
│   ├── install.ps1
│   └── run_with_env.cmd
├── appveyor.yml
├── docs/
│   ├── Makefile
│   ├── conf.py
│   ├── content/
│   │   ├── examples.rst
│   │   ├── help.rst
│   │   ├── history.rst
│   │   ├── installation.rst
│   │   └── notebook.rst
│   ├── index.rst
│   └── requirements.txt
├── poretools/
│   ├── Event.py
│   ├── Fast5File.py
│   ├── __init__.py
│   ├── combine.py
│   ├── events.py
│   ├── fasta.py
│   ├── fastq.py
│   ├── formats.py
│   ├── hist.py
│   ├── index.py
│   ├── ipynb/
│   │   └── test_run_report.ipynb
│   ├── metadata.py
│   ├── nucdist.py
│   ├── occupancy.py
│   ├── organise.py
│   ├── poretools_main.py
│   ├── qual_v_pos.py
│   ├── qualdist.py
│   ├── readstats.py
│   ├── scripts/
│   │   ├── __init__.py
│   │   ├── poretools
│   │   ├── poretools-script.py
│   │   └── poretools.bat
│   ├── squiggle.py
│   ├── statistics.py
│   ├── stats.py
│   ├── tabular.py
│   ├── times.py
│   ├── version.py
│   ├── winner.py
│   └── yield_plot.py
├── requirements.txt
├── setup.py
└── test_data/
    ├── 2016_3_4_3507_1_ch120_read240_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read353_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read415_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read418_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read433_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read443_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read505_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read521_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read542_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read586_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read635_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read706_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read83_strand.fast5
    ├── 2016_3_4_3507_1_ch120_read89_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1066_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1079_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1169_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1250_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1377_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read1387_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read160_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read217_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read223_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read249_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read324_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read326_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read382_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read42_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read501_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read562_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read601_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read618_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read700_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read743_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read831_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read833_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read843_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read857_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read899_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read914_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read940_strand.fast5
    ├── 2016_3_4_3507_1_ch126_read969_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read204_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read270_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read361_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read365_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read376_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read384_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read404_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read422_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read430_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read503_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read521_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read635_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read647_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read723_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read753_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read763_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read783_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read790_strand.fast5
    ├── 2016_3_4_3507_1_ch128_read95_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1130_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1132_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1150_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1404_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1414_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1456_strand.fast5
    ├── 2016_3_4_3507_1_ch13_read1474_strand.fast5
    ├── COLLES_L160693_20160728_FNFAB23794_MN17350_sequencing_run_E_coli_K12_1D_R9_SpotON_41280_ch52_read58_strand.fast5
    ├── YYYYMMDD_HHMM_SampleID/
    │   ├── Fail/
    │   │   ├── 0/
    │   │   │   ├── 2016_3_4_3507_1_ch120_read240_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read353_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read415_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read418_strand.fast5
    │   │   │   └── 2016_3_4_3507_1_ch120_read433_strand.fast5
    │   │   ├── 1/
    │   │   │   ├── 2016_3_4_3507_1_ch120_read443_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read505_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read521_strand.fast5
    │   │   │   ├── 2016_3_4_3507_1_ch120_read542_strand.fast5
    │   │   │   └── 2016_3_4_3507_1_ch120_read586_strand.fast5
    │   │   └── 2/
    │   │       ├── 2016_3_4_3507_1_ch120_read635_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read706_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read83_strand.fast5
    │   │       ├── 2016_3_4_3507_1_ch120_read89_strand.fast5
    │   │       └── 2016_3_4_3507_1_ch126_read1066_strand.fast5
    │   └── Pass/
    │       ├── 0/
    │       │   ├── 2016_3_4_3507_1_ch126_read1079_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1169_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1250_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read1377_strand.fast5
    │       │   └── 2016_3_4_3507_1_ch126_read1387_strand.fast5
    │       ├── 1/
    │       │   ├── 2016_3_4_3507_1_ch126_read160_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read217_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read223_strand.fast5
    │       │   ├── 2016_3_4_3507_1_ch126_read249_strand.fast5
    │       │   └── 2016_3_4_3507_1_ch126_read324_strand.fast5
    │       └── 2/
    │           ├── 2016_3_4_3507_1_ch126_read326_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read382_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read42_strand.fast5
    │           ├── 2016_3_4_3507_1_ch126_read501_strand.fast5
    │           └── 2016_3_4_3507_1_ch126_read562_strand.fast5
    ├── exp_2D_fail.fa
    ├── exp_2D_fail.fq
    ├── exp_all_nucdist
    ├── exp_all_qualdist
    ├── exp_all_stats
    ├── exp_all_winner
    ├── exp_fail_nucdist
    ├── exp_fail_qualdist
    ├── exp_pass_stats
    ├── exp_pass_winner
    ├── exp_total.fa
    ├── exp_total.fq
    └── poretools-tests.sh
Download .txt
SYMBOL INDEX (119 symbols across 25 files)

FILE: docs/conf.py
  class Mock (line 228) | class Mock(object):
    method __init__ (line 229) | def __init__(self, *args, **kwargs):
    method __call__ (line 232) | def __call__(self, *args, **kwargs):
    method __getattr__ (line 236) | def __getattr__(cls, name):

FILE: poretools/Event.py
  class Event (line 1) | class Event(object):
    method __init__ (line 8) | def __init__(self, row):
    method __repr__ (line 67) | def __repr__(self):

FILE: poretools/Fast5File.py
  class Fast5DirHandler (line 47) | class Fast5DirHandler(object):
    method __init__ (line 51) | def __init__(self, dir):
    method process (line 62) | def process(self, event):
    method on_created (line 65) | def on_created(self, event):
    method clear (line 68) | def clear(self):
    method __iter__ (line 71) | def __iter__(self):
    method next (line 74) | def next(self):
  class Fast5FileSet (line 81) | class Fast5FileSet(object):
    method __init__ (line 83) | def __init__(self, fileset, group=0):
    method get_num_files (line 93) | def get_num_files(self):
    method __iter__ (line 101) | def __iter__(self):
    method next (line 104) | def next(self):
    method _extract_fast5_files (line 113) | def _extract_fast5_files(self):
  class TarballFileIterator (line 158) | class TarballFileIterator:
    method _fast5_filename_filter (line 159) | def _fast5_filename_filter(self, filename):
    method __init__ (line 162) | def __init__(self, tarball):
    method __del__ (line 166) | def __del__(self):
    method __iter__ (line 169) | def __iter__(self):
    method next (line 172) | def next(self):
    method __len__ (line 182) | def __len__(self):
  class Fast5File (line 187) | class Fast5File(object):
    method __init__ (line 189) | def __init__(self, filename, group=0):
    method __del__ (line 213) | def __del__(self):
    method open (line 220) | def open(self):
    method guess_version (line 231) | def guess_version(self):
    method close (line 256) | def close(self):
    method has_2D (line 264) | def has_2D(self):
    method get_fastqs (line 277) | def get_fastqs(self, choice):
    method get_fastas (line 305) | def get_fastas(self, choice):
    method get_fastas_dict (line 335) | def get_fastas_dict(self):
    method get_fastq (line 346) | def get_fastq(self):
    method get_fasta (line 366) | def get_fasta(self):
    method get_template_events (line 381) | def get_template_events(self):
    method get_complement_events (line 391) | def get_complement_events(self):
    method get_pre_basecalled_events (line 401) | def get_pre_basecalled_events(self):
    method get_exp_start_time (line 415) | def get_exp_start_time(self):
    method get_channel_number (line 436) | def get_channel_number(self):
    method find_read_number_block_link (line 455) | def find_read_number_block_link(self):
    method hdf_internal_error (line 480) | def hdf_internal_error(self,reason):
    method find_read_number_block_fixed_raw (line 489) | def find_read_number_block_fixed_raw(self):
    method find_read_number_block (line 513) | def find_read_number_block(self):
    method find_event_timing_block (line 527) | def find_event_timing_block(self):
    method get_read_number (line 537) | def get_read_number(self):
    method get_start_mux (line 549) | def get_start_mux(self):
    method get_duration (line 561) | def get_duration(self):
    method get_start_time (line 581) | def get_start_time(self):
    method get_end_time (line 602) | def get_end_time(self):
    method get_version_name (line 615) | def get_version_name(self):
    method get_minknow_version (line 628) | def get_minknow_version(self):
    method get_run_id (line 641) | def get_run_id(self):
    method get_heatsink_temp (line 654) | def get_heatsink_temp(self):
    method get_asic_temp (line 667) | def get_asic_temp(self):
    method get_flowcell_id (line 680) | def get_flowcell_id(self):
    method get_host_name (line 698) | def get_host_name(self):
    method get_run_purpose (line 708) | def get_run_purpose(self):
    method get_asic_id (line 721) | def get_asic_id(self):
    method get_host_name (line 738) | def get_host_name(self):
    method get_device_id (line 755) | def get_device_id(self):
    method get_sample_name (line 769) | def get_sample_name(self):
    method get_sample_frequency (line 783) | def get_sample_frequency(self):
    method get_script_name (line 797) | def get_script_name(self):
    method get_template_events_count (line 806) | def get_template_events_count(self):
    method get_complement_events_count (line 816) | def get_complement_events_count(self):
    method is_high_quality (line 826) | def is_high_quality(self):
    method get_best_type (line 833) | def get_best_type(self):
    method _extract_fastqs_from_fast5 (line 861) | def _extract_fastqs_from_fast5(self):
    method _extract_fastas_from_fast5 (line 874) | def _extract_fastas_from_fast5(self):
    method _extract_template_events (line 887) | def _extract_template_events(self):
    method _extract_complement_events (line 897) | def _extract_complement_events(self):
    method _extract_pre_basecalled_events (line 907) | def _extract_pre_basecalled_events(self):
    method _get_metadata (line 920) | def _get_metadata(self):

FILE: poretools/combine.py
  function run (line 10) | def run(parser, args):

FILE: poretools/events.py
  function run (line 3) | def run(parser, args):

FILE: poretools/fasta.py
  function run (line 4) | def run(parser, args):

FILE: poretools/fastq.py
  function run (line 4) | def run(parser, args):

FILE: poretools/formats.py
  class Fastq (line 1) | class Fastq(object):
    method __init__ (line 2) | def __init__(self, s):
    method parse (line 6) | def parse(self):
    method __repr__ (line 9) | def __repr__(self):
    method est_error_rate (line 12) | def est_error_rate(self):
  class Fasta (line 27) | class Fasta(object):
    method __init__ (line 28) | def __init__(self, s):
    method parse (line 32) | def parse(self):
    method __repr__ (line 36) | def __repr__(self):

FILE: poretools/hist.py
  function plot_hist (line 15) | def plot_hist(sizes, args):
  function run (line 31) | def run(parser, args):

FILE: poretools/index.py
  function run (line 18) | def run(parser, args):

FILE: poretools/metadata.py
  function run (line 3) | def run(parser, args):

FILE: poretools/nucdist.py
  function run (line 4) | def run(parser, args):

FILE: poretools/occupancy.py
  function minion_flowcell_layout (line 11) | def minion_flowcell_layout():
  function plot_performance (line 24) | def plot_performance(parser, args, pore_measure):
  function run (line 53) | def run(parser, args):

FILE: poretools/organise.py
  function run (line 13) | def run(parser, args):

FILE: poretools/poretools_main.py
  function run_subtool (line 14) | def run_subtool(parser, args):
  class ArgumentParserWithDefaults (line 57) | class ArgumentParserWithDefaults(argparse.ArgumentParser):
    method __init__ (line 58) | def __init__(self, *args, **kwargs):
  function main (line 64) | def main():

FILE: poretools/qual_v_pos.py
  function run (line 11) | def run(parser, args):

FILE: poretools/qualdist.py
  function run (line 4) | def run(parser, args):

FILE: poretools/readstats.py
  function run (line 3) | def run(parser, args):

FILE: poretools/squiggle.py
  function plot_squiggle (line 15) | def plot_squiggle(args, filename, start_times, mean_signals):
  function do_plot_squiggle (line 52) | def do_plot_squiggle(args, fast5):
  function run (line 69) | def run(parser, args):

FILE: poretools/statistics.py
  function mean (line 1) | def mean(l):
  function median (line 13) | def median(l):
  function NX (line 29) | def NX(l, x=[25,50,75]):

FILE: poretools/stats.py
  function run (line 7) | def run(parser, args):

FILE: poretools/tabular.py
  function run (line 3) | def run(parser, args):

FILE: poretools/times.py
  function run (line 9) | def run(parser, args):

FILE: poretools/winner.py
  function run (line 9) | def run(parser, args):

FILE: poretools/yield_plot.py
  function plot_collectors_curve (line 15) | def plot_collectors_curve(args, start_times, read_lengths):
  function run (line 65) | def run(parser, args):
Condensed preview — 162 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,499K chars).
[
  {
    "path": ".gitignore",
    "chars": 30,
    "preview": "*.pyc\nbuild/\ndist/\n*.egg-info\n"
  },
  {
    "path": "Dockerfile",
    "chars": 1318,
    "preview": "###############################################\n# Dockerfile to build poretools container image\n# Based on Ubuntu 14.04\n"
  },
  {
    "path": "LICENSE",
    "chars": 1121,
    "preview": "The MIT License (MIT)\nCopyright © 2013,2014,2015,206,2017 Nicholas Loman, Aaron Quinlan\n\nPermission is hereby granted, f"
  },
  {
    "path": "MANIFEST.in",
    "chars": 24,
    "preview": "include requirements.txt"
  },
  {
    "path": "README.md",
    "chars": 459,
    "preview": "### poretools: a toolkit for working with nanopore sequencing data from Oxford Nanopore.\n\n*Nick Loman and Aaron Quinlan*"
  },
  {
    "path": "appveyor/install.ps1",
    "chars": 7195,
    "preview": "# Sample script to install Python and pip under Windows\n# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Al"
  },
  {
    "path": "appveyor/run_with_env.cmd",
    "chars": 3366,
    "preview": ":: To build extensions for 64 bit Python 3, we need to configure environment\n:: variables to use the MSVC 2010 C++ compi"
  },
  {
    "path": "appveyor.yml",
    "chars": 6501,
    "preview": "environment:\n  HDF5_LIBDIR: C:\\HDF5\n\n  global:\n    # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the\n   "
  },
  {
    "path": "docs/Makefile",
    "chars": 4586,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/conf.py",
    "chars": 7969,
    "preview": "# -*- coding: utf-8 -*-\n#\n# This file is execfile()d with the current directory set to its containing dir.\n#\n# Note that"
  },
  {
    "path": "docs/content/examples.rst",
    "chars": 14524,
    "preview": "###############\nUsage examples\n###############\n\n.. note::\n\n   In the following examples, ``test_data`` can be replaced w"
  },
  {
    "path": "docs/content/help.rst",
    "chars": 1759,
    "preview": "##########\nOptions\n##########\n\nThe following demonstrates the options available in ``poretools``.\n\n.. code-block:: bash\n"
  },
  {
    "path": "docs/content/history.rst",
    "chars": 515,
    "preview": "###############\nRelease History\n###############\n\nVersion 0.6.0 (29-Aug-2016)\n============================\n0. Added new `"
  },
  {
    "path": "docs/content/installation.rst",
    "chars": 5578,
    "preview": "############\nInstallation\n############\n\n\n====================\nBasic Installation\n====================\n.. code-block:: ba"
  },
  {
    "path": "docs/content/notebook.rst",
    "chars": 324,
    "preview": "################\nIPython Notebook\n################\n\nAn IPython notebook demonstrating the functionality and output of ``"
  },
  {
    "path": "docs/index.rst",
    "chars": 2204,
    "preview": "==========================================================================================\n**poretools**: *a toolkit for"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 7,
    "preview": "sphinx\n"
  },
  {
    "path": "poretools/Event.py",
    "chars": 1665,
    "preview": "class Event(object):\n\t\"\"\"\n\tVery basic class to represent a nanopore \n\ttranslocation event for a single pore\n\tbased upon "
  },
  {
    "path": "poretools/Fast5File.py",
    "chars": 24450,
    "preview": "import sys\nimport os\nimport glob\nimport tarfile\nimport shutil\nimport h5py\nimport dateutil.parser\nimport datetime\nimport "
  },
  {
    "path": "poretools/__init__.py",
    "chars": 92,
    "preview": "import os\nimport sys\nimport scripts\nfrom Fast5File import *\nfrom version import __version__\n"
  },
  {
    "path": "poretools/combine.py",
    "chars": 744,
    "preview": "import tarfile\nimport sys\nimport Fast5File\n\n#logging\nimport logging\nlogger = logging.getLogger('poretools')\n\n\ndef run(pa"
  },
  {
    "path": "poretools/events.py",
    "chars": 786,
    "preview": "import Fast5File\n\ndef run(parser, args):\n\n\t# print header.\n\tkeys = ['file', 'strand', 'mean', 'start', 'stdv', \\\n\t\t\t'len"
  },
  {
    "path": "poretools/fasta.py",
    "chars": 1382,
    "preview": "import Fast5File\nimport sys\n\ndef run(parser, args):\n\n\tfor fast5 in Fast5File.Fast5FileSet(args.files, args.group):\n\n\t\tif"
  },
  {
    "path": "poretools/fastq.py",
    "chars": 1378,
    "preview": "import Fast5File\nimport sys\n\ndef run(parser, args):\n\t\n\tfor fast5 in Fast5File.Fast5FileSet(args.files, args.group):\n\n\t\ti"
  },
  {
    "path": "poretools/formats.py",
    "chars": 830,
    "preview": "class Fastq(object):\n\tdef __init__(self, s):\n\t\tself.s = s\n\t\tself.parse()\n\n\tdef parse(self):\n\t\t(self.name, self.seq, self"
  },
  {
    "path": "poretools/hist.py",
    "chars": 1043,
    "preview": "import sys\nimport time\n\nimport matplotlib\n#matplotlib.use('Agg') # Must be called before any other matplotlib calls\nfrom"
  },
  {
    "path": "poretools/index.py",
    "chars": 2014,
    "preview": "import Fast5File\nimport datetime\n\n############\n#\n#\tindex\n#\n#   A tool to extract\n#\tall info needed to \n#\tidentify a pile"
  },
  {
    "path": "poretools/ipynb/test_run_report.ipynb",
    "chars": 1014791,
    "preview": "{\n \"metadata\": {\n  \"name\": \"\",\n  \"signature\": \"sha256:d0b818846b182639011099ca56fd583aa186cae4284de49607ba34231dc100f2\"\n"
  },
  {
    "path": "poretools/metadata.py",
    "chars": 641,
    "preview": "import Fast5File\n\ndef run(parser, args):\n\n\tif args.read:\n\t\tfor i, fast5 in enumerate(Fast5File.Fast5FileSet(args.files))"
  },
  {
    "path": "poretools/nucdist.py",
    "chars": 419,
    "preview": "import Fast5File\nfrom collections import Counter\n\ndef run(parser, args):\n\n\tnuc_count = Counter()\n\ttotal_nucs = 0\n\n\tfor f"
  },
  {
    "path": "poretools/occupancy.py",
    "chars": 2433,
    "preview": "import Fast5File\nfrom collections import Counter\nimport sys\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib im"
  },
  {
    "path": "poretools/organise.py",
    "chars": 884,
    "preview": "import Fast5File\nimport sys\nimport os\nfrom os import makedirs\nimport os.path\nimport shutil\n\n#logging\nimport logging\nlogg"
  },
  {
    "path": "poretools/poretools_main.py",
    "chars": 24578,
    "preview": "#!/usr/bin/env python\n\nimport os.path\nimport sys\nimport argparse\n\n#logger\nimport logging\nlogger = logging.getLogger('por"
  },
  {
    "path": "poretools/qual_v_pos.py",
    "chars": 2231,
    "preview": "import Fast5File\nfrom collections import defaultdict\nimport pandas\nimport matplotlib.pyplot as plt\n\n#logging\nimport logg"
  },
  {
    "path": "poretools/qualdist.py",
    "chars": 444,
    "preview": "import Fast5File\nfrom collections import Counter\n\ndef run(parser, args):\n\n\tqual_count = Counter()\n\ttotal_nucs = 0\n\n\tfor "
  },
  {
    "path": "poretools/readstats.py",
    "chars": 736,
    "preview": "import Fast5File\n\ndef run(parser, args):\n\n\tprint \"start_time\\tchannel_number\\tread_number\\ttemplate_events\\tcomplement_e"
  },
  {
    "path": "poretools/scripts/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "poretools/scripts/poretools",
    "chars": 111,
    "preview": "#!/usr/bin/python -E\n\nimport poretools.scripts\nimport poretools.poretools_main\nporetools.poretools_main.main()\n"
  },
  {
    "path": "poretools/scripts/poretools-script.py",
    "chars": 192,
    "preview": "#!C:\\Anaconda\\python.exe\n# EASY-INSTALL-SCRIPT: 'poretools==0.2.0','poretools'\n__requires__ = 'poretools==0.2.0'\nimport "
  },
  {
    "path": "poretools/scripts/poretools.bat",
    "chars": 100,
    "preview": "@echo off\nset PYFILE=%~f0\nset PYFILE=%PYFILE:~0,-4%-script.py\n\"%~f0\\..\\..\\python.exe\" \"%PYFILE%\" %*\n"
  },
  {
    "path": "poretools/squiggle.py",
    "chars": 2708,
    "preview": "import os\nimport sys\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib import rcParams\nrcParams.update({'figure."
  },
  {
    "path": "poretools/statistics.py",
    "chars": 1245,
    "preview": "def mean(l):\n\t\"\"\"\n\tReturn the mean of a list of numbers\n\t\"\"\"\n\tif isinstance(l, list):\n\t\tif len(l):\n\t\t\treturn float(sum(l"
  },
  {
    "path": "poretools/stats.py",
    "chars": 2177,
    "preview": "import statistics as stat\nimport Fast5File\nimport logging\nfrom collections import defaultdict\nlogger = logging.getLogger"
  },
  {
    "path": "poretools/tabular.py",
    "chars": 335,
    "preview": "import Fast5File\n\ndef run(parser, args):\n\t\n\tprint '\\t'.join(['length', 'name', 'sequence', 'quals'])\n\t\n\tfor fast5 in Fas"
  },
  {
    "path": "poretools/times.py",
    "chars": 1058,
    "preview": "import Fast5File\nfrom time import strftime, localtime\nimport sys\n\n#logging\nimport logging\nlogger = logging.getLogger('po"
  },
  {
    "path": "poretools/version.py",
    "chars": 23,
    "preview": "__version__ = \"0.6.0\"\n\n"
  },
  {
    "path": "poretools/winner.py",
    "chars": 482,
    "preview": "import Fast5File\nimport sys\n\n#logging\nimport logging\nlogger = logging.getLogger('poretools')\n\n\ndef run(parser, args):\n\tl"
  },
  {
    "path": "poretools/yield_plot.py",
    "chars": 3210,
    "preview": "import Fast5File\nimport matplotlib\n#matplotlib.use('Agg') # Must be called before any other matplotlib calls\nfrom matplo"
  },
  {
    "path": "requirements.txt",
    "chars": 54,
    "preview": "h5py>=2.2.0\nmatplotlib\nseaborn\npandas\npython-dateutil\n"
  },
  {
    "path": "setup.py",
    "chars": 1449,
    "preview": "import os\nfrom setuptools import setup\n\nversion_py = os.path.join(os.path.dirname(__file__), 'poretools', 'version.py')\n"
  },
  {
    "path": "test_data/exp_2D_fail.fa",
    "chars": 65093,
    "preview": ">acfc35c4-c796-443e-beca-ae3d208df6fc_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch120_read505_strand "
  },
  {
    "path": "test_data/exp_2D_fail.fq",
    "chars": 127323,
    "preview": "@acfc35c4-c796-443e-beca-ae3d208df6fc_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch120_read505_strand "
  },
  {
    "path": "test_data/exp_all_nucdist",
    "chars": 120,
    "preview": "A\t36475\t125497\t0.290644397874\nC\t26020\t125497\t0.207335633521\nT\t37002\t125497\t0.294843701443\nG\t26000\t125497\t0.207176267162\n"
  },
  {
    "path": "test_data/exp_all_qualdist",
    "chars": 715,
    "preview": "&\t5\t9\t125497\t7.17148617098e-05\n'\t6\t1570\t125497\t0.0125102592094\n(\t7\t12631\t125497\t0.100647824251\n)\t8\t23290\t125497\t0.185582"
  },
  {
    "path": "test_data/exp_all_stats",
    "chars": 109,
    "preview": "total reads\t90\ntotal base pairs\t352481\nmean\t3916.46\nmedian\t3421\nmin\t464\nmax\t10573\nN25\t7802\nN50\t5160\nN75\t3443\n"
  },
  {
    "path": "test_data/exp_all_winner",
    "chars": 10767,
    "preview": ">162acf7b-9414-49f9-a4f3-bca8c0581f78_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch126_read562_strand "
  },
  {
    "path": "test_data/exp_fail_nucdist",
    "chars": 114,
    "preview": "A\t18195\t62185\t0.292594677173\nC\t12879\t62185\t0.20710782343\nT\t18461\t62185\t0.29687223607\nG\t12650\t62185\t0.203425263327\n"
  },
  {
    "path": "test_data/exp_fail_qualdist",
    "chars": 654,
    "preview": "&\t5\t7\t62185\t0.000112567339391\n'\t6\t866\t62185\t0.0139261879875\n(\t7\t6826\t62185\t0.109769236954\n)\t8\t12180\t62185\t0.19586717054\n"
  },
  {
    "path": "test_data/exp_pass_stats",
    "chars": 109,
    "preview": "total reads\t45\ntotal base pairs\t178933\nmean\t3976.29\nmedian\t2684\nmin\t464\nmax\t10573\nN25\t8253\nN50\t6475\nN75\t3993\n"
  },
  {
    "path": "test_data/exp_pass_winner",
    "chars": 10767,
    "preview": ">162acf7b-9414-49f9-a4f3-bca8c0581f78_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch126_read562_strand "
  },
  {
    "path": "test_data/exp_total.fa",
    "chars": 370379,
    "preview": ">acfc35c4-c796-443e-beca-ae3d208df6fc_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch120_read505_strand "
  },
  {
    "path": "test_data/exp_total.fq",
    "chars": 723130,
    "preview": "@acfc35c4-c796-443e-beca-ae3d208df6fc_Basecall_2D_2d CPHG_CNU4299G4G_louse_library_2016_3_4_3507_1_ch120_read505_strand "
  },
  {
    "path": "test_data/poretools-tests.sh",
    "chars": 2502,
    "preview": "# ensure that `poretools setup.py install` is run \n# prior to running tests\n\ncheck()\n{\n    if diff $1 $2; then\n    echo "
  }
]

// ... and 99 more files (download for full content)

About this extraction

This page contains the full source code of the arq5x/poretools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 162 files (2.3 MB), approximately 621.4k tokens, and a symbol index with 119 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!