[med-svn] [r-bioc-savr] 04/06: New upstream version 1.12.0

Andreas Tille tille at debian.org
Mon Oct 2 08:25:40 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository r-bioc-savr.

commit 677212ccdf2c9414e12a86923804d397d709c06b
Author: Andreas Tille <tille at debian.org>
Date:   Mon Oct 2 10:21:23 2017 +0200

    New upstream version 1.12.0
---
 CHANGES                                            |  43 ++
 DESCRIPTION                                        |  18 +
 NAMESPACE                                          |  29 +
 R/AllClasses.R                                     | 274 +++++++++
 R/AllGenerics.R                                    | 356 +++++++++++
 R/SavR-accessors.R                                 |  82 +++
 R/savR-methods.R                                   | 666 ++++++++++++++++++++
 R/savR-package.R                                   |  24 +
 R/show-methods.R                                   |  17 +
 README.md                                          |  15 +
 build/vignette.rds                                 | Bin 0 -> 194 bytes
 debian/README.source                               |  33 -
 debian/README.test                                 |   8 -
 debian/changelog                                   |  13 -
 debian/compat                                      |   1 -
 debian/control                                     |  27 -
 debian/copyright                                   | 675 ---------------------
 debian/docs                                        |   3 -
 debian/rules                                       |   8 -
 debian/source/format                               |   1 -
 debian/tests/control                               |   3 -
 debian/tests/run-unit-test                         |  13 -
 debian/watch                                       |   3 -
 inst/doc/savR.R                                    | 101 +++
 inst/doc/savR.Rnw                                  | 196 ++++++
 inst/doc/savR.pdf                                  | Bin 0 -> 128971 bytes
 .../MiSeq/InterOp/CorrectedIntMetricsOut.bin       | Bin 0 -> 149570 bytes
 .../extdata/MiSeq/InterOp/ExtractionMetricsOut.bin | Bin 0 -> 118410 bytes
 inst/extdata/MiSeq/InterOp/QMetricsOut.bin         | Bin 0 -> 641898 bytes
 inst/extdata/MiSeq/InterOp/TileMetricsOut.bin      | Bin 0 -> 6482 bytes
 inst/extdata/MiSeq/RunInfo.xml                     |  13 +
 man/buildReports.Rd                                |  32 +
 man/clusterQualityGtN.Rd                           |  34 ++
 man/clusters.Rd                                    |  27 +
 man/correctedIntensities.Rd                        |  38 ++
 man/cycles.Rd                                      |  26 +
 man/directions.Rd                                  |  26 +
 man/errorMetrics.Rd                                |  36 ++
 man/extractionMetrics.Rd                           |  36 ++
 man/flowcellLayout.Rd                              |  27 +
 man/illuminaFlowCellLayout-class.Rd                |  22 +
 man/illuminaRead-class.Rd                          |  18 +
 man/location.Rd                                    |  26 +
 man/pfBoxplot.Rd                                   |  20 +
 man/pfClusters.Rd                                  |  28 +
 man/plotFWHM.Rd                                    |  34 ++
 man/plotIntensity.Rd                               |  33 +
 man/plotQGT30.Rd                                   |  25 +
 man/qualityHeatmap.Rd                              |  30 +
 man/qualityMetrics.Rd                              |  34 ++
 man/reads.Rd                                       |  27 +
 man/run.Rd                                         |  26 +
 man/savCorrectedIntensityFormat-class.Rd           |  22 +
 man/savData-class.Rd                               |  17 +
 man/savErrorFormat-class.Rd                        |  21 +
 man/savExtractionFormat-class.Rd                   |  23 +
 man/savFormat-class.Rd                             |  22 +
 man/savProject-class.Rd                            |  26 +
 man/savQualityFormat-class.Rd                      |  20 +
 man/savQualityFormatV5-class.Rd                    |  20 +
 man/savR-package.Rd                                |  30 +
 man/savR.Rd                                        |  30 +
 man/savTileFormat-class.Rd                         |  29 +
 man/tileMetrics.Rd                                 |  50 ++
 tests/testthat.R                                   |   4 +
 tests/testthat/test_accessors.R                    |  34 ++
 tests/testthat/test_load.R                         |  69 +++
 vignettes/savR.Rnw                                 | 196 ++++++
 68 files changed, 3052 insertions(+), 788 deletions(-)

diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..ec056e7
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,43 @@
+1.7.5 2015-07-28
+
+    * fixed issue with error metrics parsing
+
+1.7.3 2015-06-15
+
+    * basic support for NextSeq and multi-camera flowcell reads
+    * fixed logic bug when loading QMetricsOut.bin v5 
+
+1.7.2 2015-02-05
+
+    * bug fixes
+    * better handling of truncated InterOp files
+
+1.5.4 2015-02-05
+
+  General
+    * Added support for QMetricsOut.bin v5.
+    * Added ErrorMetricsOut.bin loader and getter
+    * Added clusterQualityGtN method to get the percentage of 
+    clusters that exceed a quality score for given lane
+    and cycles.
+
+1.5.3 2014-12-30:
+  
+  General
+    * fixed issue with buildReports related to update of QMetricsOut.bin change from 
+    version 4 to 5. Will now issue warning and not genrate Q>30 plot. Version 5 
+    implementation coming soon.
+      
+
+1.5.1 2014-11-12:
+
+  General
+    * bug fix for qualityHeatmap that affected paired end indexed data
+    * added getters for number of clusters and PF clusters per lane (clusters, pfClusters)
+
+1.0.0 2013-11-12:
+
+  Initial release
+
+
+
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..a90f8a1
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,18 @@
+Package: savR
+Type: Package
+Title: Parse and analyze Illumina SAV files
+Version: 1.12.0
+Date: 2015-07-28
+Author: R. Brent Calder
+Maintainer: R. Brent Calder <brent.calder at einstein.yu.edu>
+Description: Parse Illumina Sequence Analysis Viewer (SAV) files,
+    access data, and generate QC plots.
+License: AGPL-3
+URL: https://github.com/bcalder/savR
+BugReports: https://github.com/bcalder/savR/issues
+Depends: ggplot2
+Imports: methods, reshape2, scales, gridExtra, XML
+Suggests: Cairo, testthat
+biocViews: Sequencing
+NeedsCompilation: no
+Packaged: 2016-10-17 23:22:38 UTC; biocbuild
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..655494d
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,29 @@
+# Generated by roxygen2 (4.1.1): do not edit by hand
+
+export(buildReports)
+export(clusterQualityGtN)
+export(clusters)
+export(correctedIntensities)
+export(cycles)
+export(directions)
+export(errorMetrics)
+export(extractionMetrics)
+export(flowcellLayout)
+export(location)
+export(pfBoxplot)
+export(pfClusters)
+export(plotFWHM)
+export(plotIntensity)
+export(plotQGT30)
+export(qualityHeatmap)
+export(qualityMetrics)
+export(reads)
+export(run)
+export(savR)
+export(tileMetrics)
+import(XML)
+import(ggplot2)
+import(gridExtra)
+import(methods)
+import(reshape2)
+import(scales)
diff --git a/R/AllClasses.R b/R/AllClasses.R
new file mode 100644
index 0000000..31ca43c
--- /dev/null
+++ b/R/AllClasses.R
@@ -0,0 +1,274 @@
+#'Illumina read
+#'
+#'Class representation of the features of an Illumina sequencing read.
+#' 
+#'@section Slots:
+#'\describe{
+#'\item{\code{number}:}{the index of this read in sequencing}
+#'\item{\code{cycles}:}{number of cycles in this read}
+#'\item{\code{index}:}{logical representing whether or not this read is an index read}
+#'}
+setClass("illuminaRead",   slots=c(number="integer", 
+                                   cycles="integer",
+                                   index="logical"))
+
+#'Layout of an Illumina flowcell
+#'
+#'Class representation of the features of an Illumina flow cell.
+#' 
+#'@section Slots:
+#'\describe{
+#'\item{\code{lanecount}:}{Number of lanes on the flowcell}
+#'\item{\code{surfacecount}:}{Number of surfaces}
+#'\item{\code{swathcount}:}{Number of imaging swaths}
+#'\item{\code{tilecount}:}{Number of tiles per swath}
+#'\item{\code{sectionperlane}:}{Number of sections per lane (NextSeq)}
+#'\item{\code{lanepersection}:}{Number of lanes per section (NextSeq)}
+#'\item{\code{tilenamingconvention}:}{Description of deviation from original formatting layout}
+#'}
+setClass("illuminaFlowCellLayout", slots=c(lanecount="integer", 
+                                           surfacecount="integer", 
+                                           swathcount="integer", 
+                                           tilecount="integer",
+                                           sectionperlane="integer",
+                                           lanepersection="integer",
+                                           tilenamingconvention="character"
+                                           ))
+
+#'Structure for holding parsed InterOp headers and data
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{header}:}{list of parsed header values}
+#'\item{\code{data}:}{data.frame of parsed values}
+#'}
+setClass("savData", slots=c(header="list", data="data.frame", accessor="character"),
+         prototype=prototype(header=list(), data=NULL, accessor=NULL))
+
+#'SAV project class
+#' 
+#'Represents a flowcell, metadata and parsed SAV information
+#' 
+#'@section Slots:
+#'\describe{
+#'\item{\code{location}:}{Full path to flowcell directory}
+#'\item{\code{reads}:}{List of \link{illuminaRead-class}}
+#'\item{\code{layout}:}{\link{illuminaFlowCellLayout-class}}
+#'\item{\code{runid}:}{Run ID}
+#'\item{\code{number}:}{Run number}
+#'\item{\code{flowcell}:}{Flowcell ID}
+#'\item{\code{instrument}:}{Instrument ID}
+#'\item{\code{date}:}{Run date}
+#'\item{\code{cycles}:}{Total number of cycles}
+#'\item{\code{directions}:}{Total number of sequence runs (ends)}
+#'\item{\code{parsedData}:}{SAV data}
+#'}
+setClass("savProject", 
+         slots=c(location="character",	
+                 reads="list", 
+                 layout="illuminaFlowCellLayout", 
+                 runid="character", 
+                 number="integer", 
+                 flowcell="character", 
+                 instrument="character", 
+                 date="character", 
+                 cycles="integer", 
+                 directions="integer", 
+                 parsedData="list"), 
+         prototype=prototype(location="."))
+
+#'Base class for formatters
+#'
+#'Defines the necessary slots to create parse different binary files using
+#'the same generic parser.
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'\item{\code{default}:}{logical default format ()}
+#'}
+setClass("savFormat", slots=c(filename="character", 
+                              name="character", 
+                              type="character", 
+                              lengths="integer", 
+                              order="character", 
+                              version="integer",
+                              accessor="character",
+                              default="logical"))
+
+#'Corrected Intensity formatter
+#'
+#'Lane, tile, cycle, average intensity, corrected intensities (ACGT),
+#'average corrected called intensities (ACGT), number of no-calls,
+#'number of (ACGT) calls, and signal to noise ratio.
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'}
+setClass("savCorrectedIntensityFormat", contains="savFormat", 
+         prototype=prototype(filename="CorrectedIntMetricsOut.bin", 
+                             name=c("lane", "tile", "cycle", "avg_intensity", paste("avg_cor", c("A", "C", "G", "T"), sep="_"), 
+                                    paste("avg_cor_called", c("A", "C", "G", "T"), sep="_"),
+                                    paste("num", c("none", "A", "C", "G", "T"), sep="_"), 
+                                    "sig_noise"),
+                             type=c(rep("integer", 17), "numeric"),
+                             lengths=c(rep(2L,12), rep(4L, 6)),
+                             order=c("lane", "cycle", "tile"),
+                             version=2L,
+                             accessor="correctedIntensities",
+                             default=TRUE))
+
+#'Quality Metrics formatter
+#'
+#'Lane, tile, cycle, Q1-Q50 counts
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'}
+setClass("savQualityFormat", contains="savFormat", 
+         prototype=prototype(filename="QMetricsOut.bin", 
+                             name=c("lane", "tile", "cycle", paste("Q", 1:50, sep="")),
+                             type=c(rep("integer", 53)),
+                             lengths=c(rep(2L, 3), rep(4L, 50) ),
+                             order=c("lane", "cycle", "tile"),
+                             version=4L,
+                             accessor="qualityMetrics",
+                             default=TRUE))
+
+
+#'Quality Metrics formatter version 5
+#'
+#'Lane, tile, cycle, Q1-Q50 counts
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'}
+#'
+# Format information found at https://tracker.tgac.ac.uk/browse/MISO-138
+# Quality Metrics (QMetricsOut.bin)
+# Format:
+# byte 0: file version number (5)
+# byte 1: length of each record
+# byte 2: quality score binning (byte flag representing if binning was on), if (byte 2 == 1) // quality score binning on
+# byte 3: number of quality score bins, B
+# // if byte 2 == 1
+#   bytes 4 - (4+B-1): lower boundary of quality score bins
+#   bytes (4+B) - (4+2*B-1): upper boundary of quality score bins
+#   bytes (4+2*B) - (4+3*B-1): remapped scores of quality score bins
+# The remaining bytes are for the records, with each record in this format:
+# 2 bytes: lane number  (uint16)
+# 2 bytes: tile number  (uint16)
+# 2 bytes: cycle number (uint16)
+# 4 x 50 bytes: number of clusters assigned score (uint32) Q1 through Q50
+# Where N is the record index
+setClass("savQualityFormatV5", contains="savFormat", 
+         prototype=prototype(filename="QMetricsOut.bin", 
+                             name=c("lane", "tile", "cycle", paste("Q", 1:50, sep="") ),
+                             type=c(rep("integer", 53)),
+                             lengths=c(2L, 2L, 2L, rep(4L, 50)),
+                             order=c("lane", "cycle", "tile"),
+                             accessor="qualityMetrics",
+                             version=5L,
+                             default=FALSE))
+
+#'Tile Metrics formatter
+#'
+#'Lane, tile, code, value.  Codes are:
+#'
+#'\tabular{ll}{
+#'100 \tab Cluster Density \cr
+#'101 \tab PF Cluster Density \cr
+#'102 \tab Number of clusters \cr
+#'103 \tab Number of PF clusters \cr
+#'400 \tab Control lane \cr
+#'}
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number (header consists of version (1b), length (1b))}
+#'}
+setClass("savTileFormat", contains="savFormat", 
+         prototype=prototype(filename="TileMetricsOut.bin", 
+                             name=c("lane", "tile", "code", "value"),
+                             type=c(rep("integer", 3), "numeric"),
+                             lengths=c(rep(2L, 3), 4L),
+                             order=c("lane", "code", "tile"),
+                             version=2L,
+                             accessor="tileMetrics",
+                             default=TRUE))
+
+#'Extraction Metrics formatter
+#'
+#'Lane, tile, cycle, FWHM (ACGT), intensity (ACGT), datestamp, timestamp.
+#'Datestamp and timestamp are munged at the moment because R does not 
+#'have native support for 32-bit unsigned integers and I have not implemented 
+#'a solution.
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'}
+setClass("savExtractionFormat", contains="savFormat", 
+         prototype=prototype(filename="ExtractionMetricsOut.bin", 
+                             name=c("lane", "tile", "cycle", 
+                                    paste("FWHM", c("A", "C", "G", "T"), sep="_"), 
+                                    paste("int", c("A", "C", "G", "T"), sep="_"), "datestamp", "timestamp"),
+                             type=c(rep("integer", 3), rep("numeric", 4), rep("integer", 6)),
+                             lengths=c(rep(2L, 3), rep(4L,4), rep(2L,4), rep(4L,2) ),
+                             order=c("lane", "cycle", "tile"),
+                             version=2L,
+                             accessor="extractionMetrics",
+                             default=TRUE))
+
+#'Error Metrics formatter
+#'
+#'Lane, tile, cycle, errorrate, nPerfect, n1Error, n2Error,
+#'n3Error, n4Error.
+#'
+#'@section Slots:
+#'\describe{
+#'\item{\code{name}:}{vector of column names}
+#'\item{\code{type}:}{vector of data types of elements}
+#'\item{\code{lengths}:}{vector of byte lengths for each element}
+#'\item{\code{order}:}{vector of column names for sorting}
+#'\item{\code{version}:}{integer version number}
+#'}
+setClass("savErrorFormat", contains="savFormat",
+         prototype=prototype(filename="ErrorMetricsOut.bin",
+                             name=c("lane", "tile", "cycle", "errorrate", "nPerfect", paste("n", 1:4, "Error", sep="")),
+                             type=c(rep("integer", 3), "numeric", rep("integer", 5)),
+                             lengths=c(rep(2L, 3), rep(4L, 6)),
+                             order=c("lane", "cycle", "tile"),
+                             version=3L,
+                             accessor="errorMetrics",
+                             default=TRUE))
+
+setClass("savParser", slots=c(project="savProject", format="savFormat"))
+
diff --git a/R/AllGenerics.R b/R/AllGenerics.R
new file mode 100644
index 0000000..b4a0f58
--- /dev/null
+++ b/R/AllGenerics.R
@@ -0,0 +1,356 @@
+#'Build a SAV project
+#' 
+#'Constructor to build a \link{savProject-class} object and populate it. A SAV 
+#'project consists of binary files generated by an Illumina sequencing run
+#'and placed in a folder named "InterOp". This folder contains a number
+#'of ".bin" files that contain statistics about the run.  Creating
+#'this object parses all of the files and makes the data available for analysis.
+#' 
+#'@param object String Path to Flowcell data
+#'@export
+#'@examples
+#'fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+#'fc
+#'
+#'@rdname savR
+setGeneric("savR", function(object) standardGeneric("savR"))
+
+#'Get Flowcell folder location
+#'
+#'Accessor to obtain the path to data for a particular SAV project.
+#'
+#'@param project SAV project
+#'@return normalized path to Illumina run data.
+#'@export
+#'@rdname location
+#'@examples
+#'example(savR)
+#'location(fc)
+setGeneric("location", function(project) standardGeneric("location"))
+
+#'Get reads
+#'
+#'Accessor to obtain information about the reads of a particular Illumina
+#'sequencing run.
+#'
+#'@param project SAV project
+#'@return List of \link{illuminaRead-class} objects
+#'@export
+#'@rdname reads
+#'@examples
+#'example(savR)
+#'reads(fc)
+setGeneric("reads", function(project) standardGeneric("reads"))
+
+#'Get flowcell layout
+#'
+#'Accessor to obtain information about the characteristics of the flowcell
+#'from an Illumina sequencing run.
+#'
+#'@param project SAV project
+#'@return \link{illuminaFlowCellLayout-class} object
+#'@export
+#'@rdname flowcellLayout
+#'@examples
+#'example(savR)
+#'flowcellLayout(fc)
+setGeneric("flowcellLayout", function(project) standardGeneric("flowcellLayout"))
+
+#'Get the Run ID
+#'
+#'Accessor to obtain the string identifier of an Illumina sequencing run.
+#'
+#'@param project SAV project
+#'@return parsed Illumina run id
+#'@export
+#'@rdname run
+#'@examples
+#'example(savR)
+#'run(fc)
+setGeneric("run", function(project) standardGeneric("run"))
+
+#'Get the total number of cycles
+#'
+#'Accessor to obtain the total number of cycles sequenced in an Illumina sequencing run.
+#'
+#'@param project SAV project
+#'@return total number of cycles in run, including all sequencing and index reads.
+#'@export
+#'@rdname cycles
+#'@examples
+#'example(savR)
+#'cycles(fc)
+setGeneric("cycles", function(project) standardGeneric("cycles"))
+
+#'Get the number of sequence reads
+#'
+#'Returns the number of sequencing reads (excluding index reads).
+#'
+#'@param project SAV project
+#'@return number of reads
+#'@export
+#'@rdname directions
+#'@examples
+#'example(savR)
+#'directions(fc)
+setGeneric("directions", function(project) standardGeneric("directions"))
+
+#'Get Corrected Intensity data
+#'
+#'Returns a data frame of corrected intensity data.
+#'
+#' \describe{
+#'  \item{\code{lane}:}{Lane number} \cr
+#'  \item{\code{tile}:}{Tile ID} \cr
+#'  \item{\code{cycle}:}{Cycle number} \cr
+#'  \item{\code{avg_intensity}:}{Average intensity} \cr
+#'  \item{\code{avg_cor_[ACGT]}:}{Average corrected intensity of channel A, C, G, or T} \cr
+#'  \item{\code{avg_cor_called_[ACGT]}:}{Average corrected intensity for called clusters in channel A, C, G, or T} \cr
+#'  \item{\code{num_\{none|[ACGT]\}}:}{Number of called bases for no-call, A, C, G, or T} \cr
+#'  \item{\code{sig_noise}:}{Signal to noise ratio} \cr
+#' }
+#'
+#'
+#'@param project SAV project
+#'@return sorted data.frame of CI data.
+#'@export
+#'@rdname correctedIntensities
+#'@examples
+#'example(savR)
+#'colnames(correctedIntensities(fc))
+setGeneric("correctedIntensities", function(project) standardGeneric("correctedIntensities"))
+
+#'Get Quality Metrics data
+#'
+#'Quality metric by lane, tile and cycle.
+#'
+#' \describe{
+#'  \item{\code{lane}:}{Lane number}
+#'  \item{\code{tile}:}{Tile ID}
+#'  \item{\code{cycle}:}{Cycle number}
+#'  \item{\code{Q1-Q50}:}{Number of clusters with quality of indicated column}
+#' }
+#'
+#'@param project SAV project
+#'@return sorted data.frame of quality data
+#'@export
+#'@rdname qualityMetrics
+#'@examples
+#'example(savR)
+#'colnames(qualityMetrics(fc))
+setGeneric("qualityMetrics", function(project) standardGeneric("qualityMetrics"))
+
+#'Get Tile Metrics
+#'
+#'Returns the Tile Metrics SAV data.  
+#'
+#'Metrics for each tile are encoded in the following format:
+#'\tabular{ll}{
+#'cluster density: \tab 100 \cr
+#'PF cluster density: \tab 101 \cr
+#'number of clusters: \tab 102 \cr
+#'number of PF clusters: \tab 103 \cr
+#'phasing for read N: \tab (200 + (N - 1) * 2) \cr
+#'prephasing for read N: \tab (201 + (N - 1) * 2) \cr
+#'percent aligned for read N: \tab (300 + N - 1) \cr
+#'control lane: \tab 400 \cr
+#'}
+#'
+#' \describe{
+#'  \item{\code{lane}:}{Lane number}
+#'  \item{\code{tile}:}{Tile ID}
+#'  \item{\code{code}:}{Code described above}
+#'  \item{\code{value}:}{Value for code key}
+#' }
+#'
+#' 
+#'@references
+#'Codes for Tile Metrics were obtained from the Python Illuminate package: \cr
+#'\url{https://bitbucket.org/invitae/illuminate}
+#' 
+#'
+#'@param project SAV project
+#'@return sorted data.frame of tile metrics
+#'@export
+#'@rdname tileMetrics
+#'@examples
+#'example(savR)
+#'colnames(tileMetrics(fc))
+setGeneric("tileMetrics", function(project) standardGeneric("tileMetrics"))
+
+#'Get Extraction Metrics
+#'
+#'Extraction (intensity and FWHM) metrics for lane, tile, and cycle.
+#'
+#' \describe{
+#'  \item{\code{lane}:}{Lane number}
+#'  \item{\code{tile}:}{Tile ID}
+#'  \item{\code{cycle}:}{Cycle number}
+#'  \item{\code{FWHM_[ACGT]}:}{Full width at half maximum for A, C, G, or T}
+#'  \item{\code{int_[ACGT]}:}{Intensity of channel A, C, G, or T}
+#'  \item{\code{datestamp}:}{Time/date stamp}
+#' }
+#'
+#'
+#'@param project SAV project
+#'@return sorted data.frame of Extraction metrics
+#'@export
+#'@rdname extractionMetrics
+#'@examples
+#'example(savR)
+#'colnames(extractionMetrics(fc))
+setGeneric("extractionMetrics", function(project) standardGeneric("extractionMetrics"))
+
+
+#'Get Error Metrics
+#'
+#'Error metrics for lane, tile, and cycle.
+#'
+#' \describe{
+#'  \item{\code{lane}:}{Lane number}
+#'  \item{\code{tile}:}{Tile ID}
+#'  \item{\code{cycle}:}{Cycle number}
+#'  \item{\code{errorrate}:}{Error rate}
+#'  \item{\code{nPerfect}:}{number of perfect reads}
+#'  \item{\code{n[1-4]Error}:}{Number of reads with 1, 2, 3 and 4 errors}
+#' }
+#'
+#'
+#'@param project SAV project
+#'@return sorted data.frame of Error metrics
+#'@export
+#'@rdname errorMetrics
+#'@examples
+#'example(savR)
+#'colnames(extractionMetrics(fc))
+setGeneric("errorMetrics", function(project) standardGeneric("errorMetrics"))
+
+#'Plot flowcell intensity by base and cycle
+#' 
+#'Draws a representation of a flowcell, showing the average corrected called intensity values.
+#' 
+#'@param project A \link{savProject-class} object
+#'@param cycle integer cycle number
+#'@param base character for nucleotide
+#' 
+#'@export
+#'@docType methods
+#'@rdname plotIntensity
+setGeneric("plotIntensity", function(project, cycle, base) standardGeneric("plotIntensity"))
+
+#'Generate FWHM plots
+#'
+#'Plots the average full width of clusters at half maximum (FWHM) of each tile
+#'for a given cycle and base.
+#'
+#'@param project SAV project
+#'@param cycle sequence cycle
+#'@param base nucleotide base (ACGT)
+#'@export
+#'@docType methods
+#'@rdname plotFWHM
+setGeneric("plotFWHM", function(project, cycle, base) standardGeneric("plotFWHM"))
+
+#'Plot Quality > 30 for a flowcell
+#'
+#'Generate a plot for a given cycle of the percentage of clusters in each tile
+#'that are >= Q30.
+#'
+#'@param project SAV project
+#'@param cycle sequence cycle
+#'@export
+#'@docType methods
+#'@rdname plotQGT30
+setGeneric("plotQGT30", function(project, cycle) standardGeneric("plotQGT30"))
+
+#'PF Boxplot
+#'
+#'Generate a boxplot of the numbers of clusters and the number of
+#'Illumina pass-filter clusters per tile and lane
+#'
+#'@param project SAV project
+#'@export 
+#'@docType methods
+#'@rdname pfBoxplot
+setGeneric("pfBoxplot", function(project) standardGeneric("pfBoxplot"))
+
+#'Generate a heatmap of qualities
+#'
+#'Plots a heatmap of quality vs cycle for a given lane for 1 or more sequence reads.  Read qualities include sequence + index.
+#'
+#'@param project SAV project
+#'@param lane integer lane specification
+#'@param read integer vector of sequence reads to include (not including index reads)
+#'@param collapse whether or not to collapse index reads into the preceeding read (# reads = directions), default TRUE
+#'@export
+#'@docType methods
+#'@rdname qualityHeatmap
+setGeneric("qualityHeatmap", function(project, lane, read, collapse) standardGeneric("qualityHeatmap") )
+
+#'Generate Illumina reports folder
+#'
+#'Generate a folder of images that approximates the format of the folder that 
+#'was superceded by InterOp. Requires the Cairo package.
+#'
+#'@param project SAV project
+#'@param destination path to save reports folder
+#'@export
+#'@docType methods
+#'@rdname buildReports
+#'@examples
+#'\dontrun{
+#'example(savR)
+#'buildReports(fc, "reports")
+#'}
+setGeneric("buildReports", function(project, destination) standardGeneric("buildReports"))
+
+#'Get number of clusters per lane
+#'
+#'Sum the total number of clusters for all tiles in the lane.
+#'
+#'@param project SAV project
+#'@param lane lane(s) number
+#'@export
+#'@docType methods
+#'@rdname clusters
+#'@examples
+#'\dontrun{
+#'example(savR)
+#'clusters(fc, 1L)
+#'} 
+setGeneric("clusters", function(project, lane) standardGeneric("clusters"))
+
+#'Get number of PF clusters per lane
+#'
+#'Sum the total pass filter number of clusters for all tiles in the lane.
+#'
+#'@param project SAV project
+#'@param lane lane(s) number
+#'@export
+#'@docType methods
+#'@rdname pfClusters
+#'@examples
+#'\dontrun{
+#'example(savR)
+#'pfClusters(fc, 1L)
+#'} 
+setGeneric("pfClusters", function(project, lane) standardGeneric("pfClusters"))
+
+#'Get the proportion of clusters over a specified quality threshold 
+#'
+#'Return the ratio of clusters with a quality score less than or equal to 
+#'a specified value (n) for the requested lanes and cycles.
+#'
+#'@param project SAV project
+#'@param lane lane(s) number
+#'@param cycle cycle(s) number
+#'@param n quality threshold
+#'@export
+#'@docType methods
+#'@rdname clusterQualityGtN
+#'@examples
+#'\dontrun{
+#'example(savR)
+#'clusterQualityGtN(fc, 1L, 25L, 30L)
+#'}
+setGeneric("clusterQualityGtN", function(project, lane, cycle, n) standardGeneric("clusterQualityGtN"))
diff --git a/R/SavR-accessors.R b/R/SavR-accessors.R
new file mode 100644
index 0000000..bfa24c4
--- /dev/null
+++ b/R/SavR-accessors.R
@@ -0,0 +1,82 @@
+#'@rdname location
+#'@aliases location,savProject-method
+setMethod("location", signature(project="savProject"), function(project) project at location)
+
+#'@rdname reads
+#'@aliases reads,savProject-method
+setMethod("reads", signature(project="savProject"), function(project) project at reads)
+
+#'@rdname flowcellLayout
+#'@aliases flowcellLayout,savProject-method
+setMethod("flowcellLayout", signature(project="savProject"), function(project) project at layout)
+
+#'@rdname run
+#'@aliases run,savProject-method
+setMethod("run", signature(project="savProject"), function(project) project at runid)
+
+#'@rdname cycles
+#'@aliases cycles,savProject-method
+setMethod("cycles", signature(project="savProject"), function(project) project at cycles)
+
+#'@rdname directions
+#'@aliases directions,savProject-method
+setMethod("directions", signature(project="savProject"), function(project) project at directions)
+
+#'@rdname correctedIntensities
+#'@aliases correctedIntensities,savProject-method
+setMethod("correctedIntensities", signature(project="savProject"), function(project) { 
+  tmp <- project at parsedData[["savCorrectedIntensityFormat"]]@data
+  if (is.null(tmp)) return(tmp)
+  return(tmp[,!colnames(tmp) %in% c("x", "y")]) 
+})
+
+#'@rdname qualityMetrics
+#'@aliases qualityMetrics,savProject-method
+setMethod("qualityMetrics", signature(project="savProject"), function(project) { 
+  tmp <- project at parsedData[["savQualityFormat"]]@data
+  if (is.null(tmp)) return(tmp)
+  return(tmp[,!colnames(tmp) %in% c("x", "y")]) 
+})
+
+#'@rdname tileMetrics
+#'@aliases tileMetrics,savProject-method
+setMethod("tileMetrics", signature(project="savProject"), function(project) {
+  tmp <- project at parsedData[["savTileFormat"]]@data
+  return(tmp)
+})
+
+#'@rdname extractionMetrics
+#'@aliases extractionMetrics,savProject-method
+setMethod("extractionMetrics", signature(project="savProject"), function(project) { 
+  tmp <- project at parsedData[["savExtractionFormat"]]@data
+  if (is.null(tmp)) return(tmp)
+  return(tmp[,!colnames(tmp) %in% c("x", "y")]) 
+})
+
+#'@rdname errorMetrics
+#'@aliases errorMetrics,savProject-method
+setMethod("errorMetrics", signature(project="savProject"), function(project) {
+  tmp <- project at parsedData[["savErrorFormat"]]@data
+  if (is.null(tmp)) return(tmp)
+  return(tmp[,!colnames(tmp) %in% c("x", "y")])
+})
+
+#'@rdname clusters
+#@aliases clusters,savProject,integer
+setMethod("clusters", signature(project="savProject", lane="integer"), function(project, lane=1L) {
+  if (!all(lane %in% 1:flowcellLayout(project)@lanecount)) {
+    stop(paste("lane" , lane, "is not consistent with number of lanes on flowcell (", flowcellLayout(project)@lanecount, ")", sep=" "))
+  }
+  tm <- tileMetrics(project)
+  return(sum(tm[tm$lane %in% lane & tm$code==102,]$value))
+})
+
+#'@rdname pfClusters
+#'@aliases pfClusters,savProject,integer
+setMethod("pfClusters", signature(project="savProject", lane="integer"), function(project, lane=1L) {
+  if (!all(lane %in% 1:flowcellLayout(project)@lanecount)) {
+    stop(paste("lane" , lane, "is not consistent with number of lanes on flowcell (", flowcellLayout(project)@lanecount, ")", sep=" "))
+  }
+  tm <- tileMetrics(project)
+  return(sum(tm[tm$lane %in% lane & tm$code==103,]$value))
+})
\ No newline at end of file
diff --git a/R/savR-methods.R b/R/savR-methods.R
new file mode 100644
index 0000000..ed38008
--- /dev/null
+++ b/R/savR-methods.R
@@ -0,0 +1,666 @@
+# @include savR.R
+NULL
+
+#'@rdname savR
+#@aliases savR,character-method
+setMethod("savR", signature("character"), function(object) {
+  retval <- new("savProject", location=normalizePath(object))
+  retval at cycles <- 0L
+  retval at directions <- 0L
+  ri <- normalizePath(paste(object, "RunInfo.xml", sep="/"))
+  runinfo <- XML::xmlInternalTreeParse(ri)
+  retval at runid <- XML::xmlAttrs(XML::xpathApply(runinfo, "/RunInfo/Run")[[1]])["Id"]
+  retval at number <- as.integer(XML::xmlAttrs(xpathApply(runinfo, "/RunInfo/Run")[[1]])["Number"])
+  retval at flowcell <- XML::xmlValue(XML::xpathApply(runinfo, "/RunInfo/Run/Flowcell")[[1]])
+  retval at instrument <- XML::xmlValue(XML::xpathApply(runinfo, "/RunInfo/Run/Instrument")[[1]])
+  retval at date <- XML::xmlValue(XML::xpathApply(runinfo, "/RunInfo/Run/Date")[[1]])
+  reads <- c()
+  for (x in XML::xpathApply(runinfo, "/RunInfo/Run/Reads/Read")) {
+    index <- XML::xmlAttrs(x)["IsIndexedRead"]
+    index <- if(index=="Y") T else F
+    read <- new("illuminaRead", number=as.integer(XML::xmlAttrs(x)["Number"]), 
+                cycles=as.integer(XML::xmlAttrs(x)["NumCycles"]),
+                index=index)
+    reads <- c(reads, read)
+    retval at cycles <- retval at cycles + read at cycles
+    if (!read at index)
+      retval at directions <- retval at directions + 1L
+  } 
+  retval at reads <- reads
+  layout <- XML::xpathApply(runinfo, "/RunInfo/Run/FlowcellLayout")[[1]]
+  layoutChildren <- XML::xmlChildren(layout)
+  tnc <- ""
+  if (length(layoutChildren) > 0) {
+    tnc <- XML::xmlAttrs(layoutChildren$TileSet)["TileNamingConvention"]
+  }
+  retval at layout <- new("illuminaFlowCellLayout", lanecount=as.integer(XML::xmlAttrs(layout)["LaneCount"]),
+                       surfacecount=as.integer(XML::xmlAttrs(layout)["SurfaceCount"]),
+                       swathcount=as.integer(XML::xmlAttrs(layout)["SwathCount"]),
+                       tilecount=as.integer(XML::xmlAttrs(layout)["TileCount"]),
+                       sectionperlane=as.integer(XML::xmlAttrs(layout)["SectionPerLane"]),
+                       lanepersection=as.integer(XML::xmlAttrs(layout)["LanePerSection"]),
+                       tilenamingconvention=as.character(tnc)
+                       )
+  return(init(retval))
+} )
+
+#'@rdname savR
+#@aliases savR,missing-method
+setMethod("savR", signature("missing"), function() { savR(".") })
+
+subsetSide <- function(data, side) {
+  if (side=="top") {
+    data <- data[grepl(".1..", data$tile),]
+  } else if (side=="bottom") {
+    data <- data[grepl(".2..", data$tile),]
+  }
+  return(data)
+}
+
+
+
+#'@rdname plotIntensity
+#@aliases plotIntensity,savProject,integer,character-method
+setMethod("plotIntensity", signature(project="savProject", cycle="integer", base="character"), function(project, cycle=1L, base=c("A", "C", "G", "T")) {
+  x <- y <- NULL
+  if (cycle < 0)
+    stop ("Cycle out of range")
+  data <- project at parsedData[["savCorrectedIntensityFormat"]]@data
+  if (is.null(data))
+    stop("Corrected Intensity data not available")
+  val <- paste("avg_cor_called", c("A", "C", "G", "T"), sep="_") 
+  names(val) <- c("A", "C", "G", "T")
+  maxInt <- max(c(data[, val["A"]], data[, val["C"]], data[, val["G"]], data[, val["T"]]))
+  if(maxInt < 7000) {
+    maxInt <= 7000
+  }
+  data <- data[data$cycle==cycle,]
+  base <- match.arg(base)
+  
+  p <- qplot(factor(x),y,fill=get(val[base]), data=data, geom="tile", position="dodge", main = paste("Intensity: ", base, ", Cycle ", cycle, sep="")) + 
+    theme_bw() + theme(legend.position = "bottom") + scale_fill_continuous(guide = guide_colorbar(title=val, barwidth=10), limits=c(0,maxInt) ) + 
+    facet_grid(~lane, space="free", scales="free") + 
+    xlab("") + ylab("") + scale_x_discrete(labels="") 
+  gridExtra::grid.arrange(p)
+} )
+
+#'@rdname plotIntensity
+#@aliases plotIntensity,savProject,missing,missing-method
+setMethod("plotIntensity", signature(project="savProject", cycle="missing", base="missing"), function(project) { plotIntensity(project, 1L, "A")})
+#'@rdname plotIntensity
+#@aliases plotIntensity,savProject,integer,missing-method
+setMethod("plotIntensity", signature(project="savProject", cycle="integer", base="missing"), function(project, cycle) { plotIntensity(project, cycle, "A")})
+#'@rdname plotIntensity
+#@aliases plotIntensity,savProject,missing,character-method
+setMethod("plotIntensity", signature(project="savProject", cycle="missing", base="character"), function(project, base) { plotIntensity(project, 1L, base)})
+
+
+
+#'@rdname plotFWHM
+#@aliases plotFWHM,savProject,integer,character-method
+setMethod("plotFWHM", signature(project="savProject", cycle="integer", base="character"), function(project, cycle=1L, base=c("A", "C", "G", "T")) {
+  x <- y <- NULL
+  if (cycle < 0)
+    stop ("Cycle out of range")
+  data <- project at parsedData[["savExtractionFormat"]]@data
+  if (is.null(data))
+    stop("Extraction data not available")
+  data <- data[data$cycle==cycle,]
+  base <- match.arg(base)
+  val <- paste("FWHM", base, sep="_")
+  p <- qplot(factor(x),y,fill=get(val), data=data, geom="tile", position="dodge", main = paste("Intensity: ", base, ", Cycle ", cycle, sep="")) + 
+    theme_bw() + theme(legend.position = "bottom") + scale_fill_continuous(guide = guide_colorbar(title=val, barwidth=10), limits=c(0,10) ) +
+    facet_grid(~lane, space="free", scales="free") +
+    xlab("") + ylab("") + scale_x_discrete(labels="") 
+  gridExtra::grid.arrange(p)
+} )
+
+#'@rdname plotFWHM
+#@aliases plotFWHM,savProject,missing,missing-method
+setMethod("plotFWHM", signature(project="savProject", cycle="missing", base="missing"), function(project) { plotFWHM(project, 1L, "A")})
+#'@rdname plotFWHM
+#@aliases plotFWHM,savProject,integer,missing-method
+setMethod("plotFWHM", signature(project="savProject", cycle="integer", base="missing"), function(project, cycle) { plotFWHM(project, cycle, "A")})
+#'@rdname plotFWHM
+#@aliases plotFWHM,savProject,missing,character-method
+setMethod("plotFWHM", signature(project="savProject", cycle="missing", base="character"), function(project, base) { plotFWHM(project, 1L, base)})
+
+#Get formatted data for Q GT30 plot
+#
+#@param data data.frame
+#@param cycle cycle
+getFormatQGT30 <- function(data, cycle=1L) {
+  #side <- match.arg(side)
+  #data <- subsetSide(data,side)
+  stats <- getFlowcellStats(data)
+  contenders <- as.integer(gsub("Q", "", colnames(data)[grepl("^Q", colnames(data))]))
+  lt30 <- paste("Q", 1:30, sep="")
+  gte30 <- paste("Q", 31:max(contenders), sep="")
+  return(cbind(data[data$cycle==cycle, c("cycle", "lane", "tile")], 
+               x=factor(rep(1:(stats$nswath*stats$nsides*stats$nlanes), each=stats$ntiles)), 
+               y=rep(1:stats$ntiles, stats$nswath*stats$nsides),
+               gte30=apply(data[data$cycle==cycle,], 1, function(x) { 
+                 return(sum(x[gte30])/(sum(x[c(lt30, gte30)])+.00001)*100 )
+               })
+  ))
+}
+
+
+
+#'@rdname plotQGT30
+#@aliases plotQGT30,savProject,integer-method
+setMethod("plotQGT30", signature(project="savProject", cycle="integer"), function(project, cycle=1L) {
+  x <- y <- gte30 <- NULL
+  if (cycle < 0)
+    stop ("Cycle out of range")
+  data <- project at parsedData[["savQualityFormat"]]@data
+  if (is.null(data))
+    stop("Quality data not available")
+  cycleData <- getFormatQGT30(data, cycle)
+  p <- qplot(x, y, fill=gte30, data=cycleData, geom="tile", position="dodge", main = paste("Percent Q>=30, Cycle ", cycle, sep="")) + 
+    theme_bw() + theme(legend.position = "bottom") + scale_fill_continuous(guide = guide_colorbar(title="%Q>=30", barwidth=10), limits=c(0,100) ) +
+    facet_grid(~lane, space="free", scales="free") +
+    xlab("") + ylab("") + scale_x_discrete(labels="") 
+  gridExtra::grid.arrange(p)
+} )
+
+#'@rdname plotQGT30
+#@aliases plotQGT30,savProject,missing-method
+setMethod("plotQGT30", signature(project="savProject", cycle="missing"), function(project) { plotQGT30(project, 1L)})
+
+
+
+#'@rdname pfBoxplot
+#@aliases pfBoxplot,savProject-method
+setMethod("pfBoxplot", signature("savProject"), function(project) {
+  lane <- value <- code <- NULL
+  data <- project at parsedData[["savTileFormat"]]@data
+  if (is.null(data))
+    stop("Tile data not available")
+  data <- data[data$code %in% c(100,101),]
+  data[data$code==100, "code"] <- "Clusters"
+  data[data$code==101, "code"] <- "PF"
+  p <- ggplot2::ggplot(data, ggplot2::aes(factor(lane), value)) + ggplot2::geom_boxplot(notch=F, ggplot2::aes(fill = code), alpha=.8) + ggplot2::ylim(0,max(data$value)) +
+    ggplot2::theme_bw() + ggplot2::theme(legend.position = "bottom") + 
+    ggplot2::labs(list(y=expression(paste("Clusters/", mm^2, sep="")), x="Lane", fill=""))
+  gridExtra::grid.arrange(p)
+} )
+
+#format quality data
+#
+#@param data data
+#@param lane lane
+#@param cycles cycles
+#@return formatted data
+qFormat <- function(data,lane,cycles,collapse=T) {
+  data <- data[data$lane==lane & data$cycle %in% cycles, ]
+  quals <- paste("Q", 1:50, sep="")
+  mat <- reshape2::melt(data[,c("cycle",quals)], id=c("cycle"), measured=quals)
+  mat <- reshape2::dcast(mat, cycle ~ variable, sum)
+  mat <- reshape2::melt(mat, id=c("cycle"), measured=quals)
+  mat[,2] <- as.numeric(gsub("Q", "", mat[,2]))
+  colnames(mat) <- c("x", "y", "z")
+  return(mat)
+}
+
+#read number to vector of cycle numbers
+#
+#@param project SAV project
+#@param read read number
+#@return vector of cycle numbers
+readToCycles <- function(project, read) {
+  cycles <- c()
+  indexed <- c()
+  for (x in project at reads) {
+    cycles <- c(cycles, x at cycles)
+    indexed <- c(indexed, x at index)
+  }
+  seqreadlen <- vector("integer", sum(!indexed))
+  r <- 0
+  for (i in 1:length(indexed)) {
+    if (!indexed[i]) {
+      r <- r + 1
+    } 
+    seqreadlen[r] <- seqreadlen[r] + cycles[i]      
+  }
+  start <- 1
+  end <- 0
+  result <- list()
+  for (r in 1:length(seqreadlen)) {
+    end <- end + seqreadlen[r]
+    result[[r]] <- start:end
+    start <- start + seqreadlen[r]
+  }
+  return(result[[read]])     
+}
+
+
+
+#'@rdname qualityHeatmap
+#@aliases qualityHeatmap,savProject,integer,integer,logical-method
+setMethod("qualityHeatmap", signature(project="savProject", lane="integer", read="integer", collapse="logical"), function(project, lane, read, collapse=T) {
+  y <- z <- ..level.. <- NULL
+  plots <- list()
+  nsegments <- directions(project)
+  if (!collapse)
+    nsegments <- length(reads(project))
+  # TODO: collapse segments
+  if (!all( read %in% 1:nsegments))
+    stop(paste("There are only", directions(project), "sequence read(s) and ", length(reads(project)), "total read segments on this flowcell, check read specification."))
+  formatName <- names(project at parsedData)[pmatch("savQualityFormat", names(project at parsedData))]
+  
+  for (x in 1:length(read)) {
+    mat <- qFormat(data=project at parsedData[[formatName]]@data, lane=lane, cycles=readToCycles(project, read[x]), collapse)
+    plots[[x]] <- ggplot2::ggplot(mat, ggplot2::aes(x=x, y=y, z=z)) + 
+      ggplot2::stat_contour(bins=50, geom="polygon", ggplot2::aes(fill=..level..)) + ggplot2::ylim(0,50) + 
+      ggplot2::theme_bw() + ggplot2::scale_fill_gradient2(low="white", mid=scales::muted("green"), high="red", midpoint=quantile(mat$z, .99) ) + 
+      xlab("cycle") + ylab("Q")
+  }
+  do.call(gridExtra::grid.arrange, c(plots, ncol=length(plots)))
+} )
+
+#'@rdname qualityHeatmap
+#@aliases qualityHeatmap,savProject,numeric,numeric,missing-method
+setMethod("qualityHeatmap", signature(project="savProject", lane="numeric", read="numeric", collapse="missing"), function(project, lane, read) { qualityHeatmap(project, as.integer(lane), as.integer(read), collapse=TRUE)})
+
+
+#'@rdname buildReports
+#@aliases buildReports,savProject,character-method
+setMethod("buildReports", signature(project="savProject", destination="character"), function(project, destination="./savR-reports") {
+  path <- location(project)
+  if (!file.exists(path))
+    stop(paste("Project", path, "does not exist."))
+  reports <- normalizePath(destination, mustWork=F)
+  if (file.exists(reports))
+    stop(paste("Reports folder", reports, "already exists."))
+  for (f in c("ByCycle", "ErrorRate", "FWHM", "Intensity", "NumGT30")) {
+    assign(f, paste(reports, f, sep="/"))
+    dir.create(get(f), showWarnings=F, recursive=T)
+  }
+  # PF plot
+  Cairo::Cairo(file=paste(reports, "/NumClusters By Lane.png", sep=""), width=800, height=400, dpi=72, type="png", bg="white")
+  pfBoxplot(project)
+  dev.off()
+  # intensity plots
+  path <- normalizePath(paste(reports, "Intensity", sep="/"))
+  for (cycle in 1:project at cycles) {
+    for (base in c("A", "C", "G", "T")) {
+      tryCatch({
+        Cairo::Cairo(file=paste(path, "/Chart_", cycle, "_", tolower(base), ".png", sep=""), width=300, height=800, dpi=72, type="png", bg="white")
+        plotIntensity(project, cycle, base)
+        dev.off()},
+        warning = function(w) {
+          return()
+        },
+        error = function(e) {
+          warning("Unable to create intensity plot for cycle ", cycle , " base ", base, ": ", geterrmessage())
+        },
+        finally = {
+          try(dev.off(), silent=TRUE)
+        })
+    }
+  }
+  # Q>30 plots
+  path <- normalizePath(paste(reports, "NumGT30", sep="/"))
+  for (cycle in 1:project at cycles) {
+    tryCatch({
+      Cairo::Cairo(file=paste(path, "/Chart_", cycle, ".png", sep=""), width=300, height=800, dpi=72, type="png", bg="white")
+      plotQGT30(project, cycle)
+      dev.off()},
+      warning = function(w) {
+        return()
+      },
+      error = function(e) {
+        warning("Unable to create Q>30 plot for cycle ", cycle, ": ", geterrmessage())
+      },
+      finally = {
+        try(dev.off(), silent=TRUE)
+      })
+  }
+  
+  
+  # plot lane quality
+  path <- normalizePath(paste(reports, "ByCycle", sep="/"))
+  for (lane in 1:project at layout@lanecount) {
+    tryCatch({
+      Cairo::Cairo(file=paste(path, "/QScore_L", lane, ".png", sep=""), width=800, height=400, dpi=72, type="png", bg="white")
+      qualityHeatmap(project, lane, 1:project at directions)
+      dev.off()},
+      warning = function(w) {
+        return()
+      },
+      error = function(e) {
+        warning("Unable to create lane quality plot for lane ", lane, ": ", geterrmessage())
+      },
+      finally = {
+        try(dev.off(), silent=TRUE)
+      })
+  } 
+  
+  # FWHM plots
+  path <- normalizePath(paste(reports, "FWHM", sep="/"))
+  for (cycle in 1:project at cycles) {
+    for (base in c("A", "C", "G", "T")) {
+      tryCatch({
+        Cairo::Cairo(file=paste(path, "/Chart_", cycle, "_", tolower(base), ".png", sep=""), width=300, height=800, dpi=72, type="png", bg="white")
+        plotFWHM(project, cycle, base)
+        dev.off()},
+        warning = function(w) {
+          return()
+        },
+        error = function(e) {
+          warning("Unable to create FWHM plot for cycle ", cycle, " base ", base, ": ", geterrmessage())
+        },
+        finally = {
+          try(dev.off(), silent=TRUE)
+        })
+    }
+  }  
+  
+} )
+
+#'@rdname buildReports
+#@aliases buildReports,savProject,missing-method
+setMethod("buildReports", signature(project="savProject", destination="missing"), function(project) { buildReports(project, "./savR-reports")})
+
+
+#Generic binary parser
+#
+#@param project SAV project
+#@param format savFormat subclass to define data types
+#@return sorted data.frame of parsed data)
+parseBin <- function(project, format) {
+  path <- getInterOpFilePath(project, format)
+  fh <- file(path, "rb")
+  vers <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  if (vers != format at version) {
+    close(fh)
+    warning(paste(" the generic savR parser currently only supports version", format at version, "of this SAV file.", format at filename, "is reported as version", vers, "."))
+    return(NULL)
+  }
+  reclen <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  if (reclen != sum(format at lengths))
+    stop(paste("file's declared record size (", reclen, ") does not equal formats declared size (", sum(format at lengths), ")"))
+  
+  data.f <- parseBinData(project,format,fh)
+  
+  close(fh)
+  
+  result <- new("savData", header=list(version=vers, record_length=reclen), data=data.f, accessor=format at accessor)
+  
+  return(result)
+} 
+
+parseBinData <- function(project, format, fh) {
+  readlen <- 0
+  for (x in project at reads) {
+    readlen <- readlen + x at cycles
+  }
+  proj.size <- 0
+  if (project at layout@tilenamingconvention == "FiveDigit") {
+    proj.size <- project at layout@lanecount * project at layout@surfacecount *
+      project at layout@swathcount * project at layout@sectionperlane *
+      project at layout@lanepersection * project at layout@tilecount * readlen + 1
+  } else {
+    proj.size <- project at layout@lanecount * project at layout@surfacecount * 
+      project at layout@swathcount * project at layout@tilecount * readlen + 1
+  }
+  data <- vector("list", proj.size)
+  r <- 1
+  while (!isIncomplete(fh)) {
+    dat <- c()
+    for (i in 1:length(format at lengths)) {
+      if (format at type[i] != "integer") {
+        dat <- c(dat, readBin(fh, what=format at type[i], size=format at lengths[i], endian="little"))
+      } else if (format at type[i] == "integer" & format at lengths[i] == 2L) {
+        dat <- c(dat, readBin(fh, what=format at type[i], size=format at lengths[i], endian="little", signed=F))
+      } else {
+        # R does not handle 32-bit unsigned int :/
+        dat <- c(dat, readBin(fh, what=format at type[i], size=format at lengths[i], endian="little"))
+      }
+    }
+    if (length(dat)==0)
+      break
+    if(length(dat) == length(format at lengths)) {
+      data[[r]] <- dat
+    } else {
+      warning(format at filename, " prematurely terminated with incomplete row at ", r)
+      break
+    }
+    r <- r + 1
+  }
+  # remove NULL rows
+  data.f <- as.data.frame(do.call("rbind", data[!unlist(lapply(data, is.null))] ))
+  colnames(data.f) <- format at name
+  actnum <- length(unique(data.f[,"lane"]))
+  if (format at filename == "ErrorMetricsOut.bin") {
+    # no consistent way to determine which lanes were called?
+  } else if (actnum != project at layout@lanecount) {
+    stop(paste("number of lanes in data file (", actnum, ") does not equal project configuration value (", 
+      project at layout@lanecount, ") when parsing ", format at filename, sep=""))
+  }
+  data.f <- data.f[do.call(order, as.list(data.f[,format at order])),]
+  return(data.f)
+}
+
+#validParser <- function(object) {
+#  if (length(object at format@name) != length(object at format@type) & length(object at format@type) != length(object at format@size))
+#    return("length of format parameters are not equal.")
+#  TRUE
+#}
+
+#setValidity("savParser", validParser)
+
+#Get basic flowcell statistics
+#
+#used to get flowcell information when data object has
+#lane, cycle, and tile data.
+#
+#@param data.frame of parsed data
+#@return list of statistics
+getFlowcellStats <- function(object) {
+  retval <- list()
+  retval$sides  <- as.numeric(substring(object$tile,1,1))
+  retval$swaths <- as.numeric(substring(object$tile,2,2))
+  retval$tiles  <- as.numeric(substring(object$tile,3,4))
+  retval$nsides <- as.numeric(length(unique(substring(object$tile,1,1))))
+  retval$nswath <- as.numeric(length(unique(substring(object$tile,2,2))))
+  retval$ntiles <- as.numeric(substr(max(object$tile),3,4))
+  retval$ncycle <- max(object$cycle)
+  retval$nlanes <- max(object$lane)
+  return(retval)
+} 
+
+#Add position data to parsed data
+#
+#Adds and x and a y column to parsed data.  These are used for
+#laying out tiles in a tile plot.  Values are organized by
+#lane, then by swath and surface.
+#
+#@param data data.frame of parsed data
+#@return annotated data.frame
+addPosition <- function(data) {
+  ##< addPosition
+  ### This is an internal method for annotating flowcell data with XY coordinates
+  ### used in tile plots of flowcell lanes.
+  stats <- getFlowcellStats(data)
+
+  return(cbind(data, 
+               x=( (data$lane-1) * (stats$nswath*stats$nside) + 1 ) + 
+                 (stats$swaths-1) + 
+                 ( (stats$sides-1) * stats$nsides + (stats$sides-1) ), 
+               #y=rep(rep(1:stats$ntiles, stats$nswath*stats$nsides*stats$ncycle), stats$nlanes)
+               y=stats$tiles
+               ))
+} 
+
+#Do parsing
+#
+#After everything is configured, initialize parsing of SAV files.
+#
+#@param project SAV project
+init <- function(project) {
+  validFormats <- c("savCorrectedIntensityFormat", 
+                    "savQualityFormat",
+                    "savQualityFormatV5", 
+                    "savTileFormat", 
+                    "savExtractionFormat",
+                    "savErrorFormat")
+  
+  fileSuccess <- list()
+  
+  for (x in validFormats) {
+    format <- new(x)
+    
+    if (is.null(fileSuccess[[format at filename]])) {
+      fileSuccess[format at filename] <- FALSE
+    }
+    
+    filePath <- suppressWarnings(normalizePath(paste(project at location, "InterOp", format at filename, sep="/") ))
+    
+    if (file.exists(filePath)) {
+      
+      if (fileSuccess[format at filename] == TRUE || !testVersion(project,format)) next
+
+      parsedData <- NULL
+      data <- NULL
+      success <- FALSE
+      
+      tryCatch({
+        if (format at default == T) {
+          parsedData <- parseBin(project, format)
+        } else {
+          f <- get(paste("parse", x, sep=""))
+          parsedData <- f(project, format)
+        }
+        success <- TRUE
+      },
+      error = function(e) {
+        warning("Unable to parse binary data: ", geterrmessage())
+      },
+      finally = {
+      })
+      
+      if (success == FALSE) next
+      
+      fileSuccess[format at filename] <- success      
+      
+      data <- parsedData at data
+      
+      if (!is.null(data)) {
+        # don't add position data to tiles
+        if (class(format)[1] != "savTileFormat" )
+          data <- addPosition(data)
+        # removed unparsed date columns
+        if (class(format)[1] == "savExtractionFormat")
+          data <- data[,-c(12:13)]
+      }
+      
+      parsedData at data <- data
+      
+      project at parsedData[[x]] <- parsedData
+    }
+  }
+  return(project)
+} 
+
+#
+# test the version of the file against the formatter
+testVersion <- function(project, format) {
+  matched <- FALSE
+  path <- normalizePath(paste(project at location, "InterOp", format at filename, sep="/"))
+  fh <- file(path, "rb")
+  vers <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  close(fh)
+  if (length(vers) == 0) {
+    warning(paste("Unable to determine file version: empty", format at filename, "binary file?", sep=" "))
+    vers <- -1
+  }
+  if (vers == format at version) {
+    matched <- TRUE 
+  }
+  return(matched)
+}
+
+getInterOpFilePath <- function(project, format) {
+  return(normalizePath(paste(project at location, "InterOp", format at filename, sep="/")))
+}
+
+#
+# taken from: https://tracker.tgac.ac.uk/browse/MISO-138
+# 
+# Quality Metrics (QMetricsOut.bin)
+# Format:
+#  byte 0: file version number (5)
+#  byte 1: length of each record
+#  byte 2: quality score binning (byte flag representing if binning was on), if (byte 2 == 1) // quality score binning on
+#  byte 3: number of quality score bins, B
+#  bytes 4 - (4+B-1): lower boundary of quality score bins
+#  bytes (4+B) - (4+2*B-1): upper boundary of quality score bins
+#  bytes (4+2*B) - (4+3*B-1): remapped scores of quality score bins
+# The remaining bytes are for the records, with each record in this format:
+#  2 bytes: lane number  (uint16)
+#  2 bytes: tile number  (uint16)
+#  2 bytes: cycle number (uint16)
+#  4 x 50 bytes: number of clusters assigned score (uint32) Q1 through Q50
+# Where N is the record index
+#
+#
+# variable length header SAV Quality Formatter (version 5)
+parsesavQualityFormatV5 <- function(project, format) {
+  path <- getInterOpFilePath(project,format)
+  fh <- file(path, "rb")
+  vers <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  reclen <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  binning <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+  
+  lowB <- c()
+  upB <- c()
+  remapB <- c()
+  nBins <- 0
+ 
+  if (binning == 1) { 
+    nBins <- readBin(fh, what="integer", endian="little", size=1, signed=F)
+    for (x in 1:nBins) {
+      lowB <- c(lowB, readBin(fh, what="integer", endian="little", size=1, signed=F))
+    }
+    for (x in 1:nBins) {
+      upB <- c(upB, readBin(fh, what="integer", endian="little", size=1, signed=F))
+    }
+    for (x in 1:nBins) {
+      remapB <- c(remapB, readBin(fh, what="integer", endian="little", size=1, signed=F))
+    }
+  }
+  
+  # end header processing
+  
+  parsedData <- new("savData", 
+                    header=list(version=vers, record_length=reclen, binning=binning, nBins=nBins,
+                                           lowBound=lowB, upperBound=upB, remappedScores=remapB),
+                    data=parseBinData(project,format,fh),
+                    accessor=format at accessor)
+  
+  close(fh)
+  
+  return(parsedData)
+  
+}
+
+#'@rdname clusterQualityGtN
+#'@aliases clusterQualityGtN,savProject,integer,integer,integer
+setMethod("clusterQualityGtN", signature(project="savProject", lane="integer", cycle="integer", n="integer"),
+          function(project, lane, cycle, n=30L) {
+            if (!all(lane %in% 1:flowcellLayout(project)@lanecount)) {
+              stop(paste("lane" , lane, "is not consistent with number of lanes on flowcell (", flowcellLayout(project)@lanecount, ")", sep=" "))
+            }
+            qm <- qualityMetrics(project)
+            qm <- qm[qm$lane == lane,]
+            if (!all(cycle %in% 1:max(qm$cycle))) {
+              stop(paste("cycles" , cycle, "is not consistent with number of cycles (", max(qm at cycle), ")", sep=" "))
+            }
+            qm <- qm[qm$cycle %in% cycle, paste("Q", 1:50, sep="")]
+            
+            tot <- sum(qm)
+            
+            return(sum(qm[,paste("Q", n:50, sep="")])/tot)
+})
diff --git a/R/savR-package.R b/R/savR-package.R
new file mode 100644
index 0000000..b0cd13d
--- /dev/null
+++ b/R/savR-package.R
@@ -0,0 +1,24 @@
+#'Parse Illumina Sequence Analysis Viewer files 
+#' 
+#'\tabular{ll}{
+#'Package: \tab savR \cr
+#'Type: \tab Package \cr
+#'Version: \tab 1.7.5 \cr
+#'Date: \tab 2015-07-28 \cr
+#'License: \tab AGPL-3 \cr
+#'LazyLoad: \tab yes \cr
+#'}
+#' 
+#'Parse Illumina Sequence Analysis Viewer (SAV) 
+#'files, access data, and generate QC plots.
+#' 
+#'@name savR-package
+#'@docType package
+#'@import methods ggplot2 reshape2 scales gridExtra XML
+#'@title Parse and analyze Illumina SAV files
+#'@author R. Brent Calder \email{brent.calder@@einstein.yu.edu}
+#'@references For information about Illumina SAV, please refer to \cr \url{http://supportres.illumina.com/documents/documentation/software_documentation/sav/sequencinganalysisviewer_userguide_15020619c.pdf} \cr For other implementations (and inspiration) please see \cr \url{http://search.cpan.org/dist/Bio-IlluminaSAV/Bio/IlluminaSAV.pm} \cr \url{https://bitbucket.org/invitae/illuminate}
+#'@keywords package
+#' 
+NULL
+
diff --git a/R/show-methods.R b/R/show-methods.R
new file mode 100644
index 0000000..3bb39df
--- /dev/null
+++ b/R/show-methods.R
@@ -0,0 +1,17 @@
+setMethod("show", "savProject", function(object) cat(class(object), "instance with", 
+                                                     object at layout@lanecount, "lanes,", 
+                                                     object at cycles, "total cycles, and",
+                                                     length(reads(object)), "sequence reads (",
+                                                     object at directions, "sequencing and ",
+                                                     length(reads(object))-object at directions, "indexed reads ).\n",
+                                                     if(object at layout@tilenamingconvention != "") { 
+                                                       paste("Indicated tile naming convention: ",
+                                                             object at layout@tilenamingconvention, ".\n", sep="")} else
+                                                               {"Default naming convention.\n"},
+                                                     "With InterOp data for:", 
+                                                     paste(" ", names(object at parsedData), 
+                                                           " (", 
+                                                           sapply(names(object at parsedData), FUN = function(x) { 
+                                                             x <- new(x); return(x at accessor)
+                                                             }), ")\n", sep = ""), "\n")
+)
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5aaab4c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+savR
+================================
+
+*savR* is an R package to parse Illumina Sequence Analysis Viewer (InterOp)
+files for downstream analysis.
+
+Current release version 1.7.5.
+
+Example
+--------
+
+```
+library(savR)
+example(savR)
+```
diff --git a/build/vignette.rds b/build/vignette.rds
new file mode 100644
index 0000000..f20bac6
Binary files /dev/null and b/build/vignette.rds differ
diff --git a/debian/README.source b/debian/README.source
deleted file mode 100644
index 8602470..0000000
--- a/debian/README.source
+++ /dev/null
@@ -1,33 +0,0 @@
-Explanation for binary files inside source package according to
-  http://lists.debian.org/debian-devel/2013/09/msg00332.html
-
-Files: inst/extdata/MiSeq/InterOp/CorrectedIntMetricsOut.bin
-Documentation: inst/doc/savR.Rnw
- Corrected intensitites
- .
- Corrected intensity metrics can be inspected by the correctedIntestites
- accessor method
-
-Files: inst/extdata/MiSeq/InterOp/ExtractionMetricsOut.bin
-Documentation: inst/doc/savR.Rnw
- Extraction Metrics
- .
- The extraction metrics file contains per-lane/cycle/tile information about
- per-base FWHM (full width pixel size of clusters at half maximum) and
- 90th %-ile intensity of signal intensity.
-
-Files: inst/extdata/MiSeq/InterOp/QMetricsOut.bin
-Documentation: inst/doc/savR.Rnw
- Quality Metrics
- .
- The quality metrics file contains per-lane/tile/cycle metrics for the number
- of clusters with quality at each PHRED value from 1-50.
-
-Files: inst/extdata/MiSeq/InterOp/TileMetricsOut.bin
-Documentation: inst/doc/savR.Rnw
- Tile Metrics
- .
- The tile metrics file contains coded information about per-lane/cycle/tile
- cluster density, pass-filter clusters, phasing and pre-phasing data.
-
- -- Andreas Tille <tille at debian.org>  Thu, 18 Aug 2016 11:01:11 +0200
diff --git a/debian/README.test b/debian/README.test
deleted file mode 100644
index 53fb4d7..0000000
--- a/debian/README.test
+++ /dev/null
@@ -1,8 +0,0 @@
-Notes on how this package can be tested.
-────────────────────────────────────────
-
-This package can be tested by running the provided test:
-
-   sh ./run-unit-test
-
-in order to confirm its integrity.
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 469ffbc..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,13 +0,0 @@
-r-bioc-savr (1.12.0-1) unstable; urgency=medium
-
-  * New upstream version
-  * Convert to dh-r
-  * Generic BioConductor homepage
-
- -- Andreas Tille <tille at debian.org>  Mon, 07 Nov 2016 13:50:46 +0100
-
-r-bioc-savr (1.10.0-1) unstable; urgency=low
-
-  * Initial release (closes: #834720)
-
- -- Andreas Tille <tille at debian.org>  Thu, 18 Aug 2016 12:02:23 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 74fda9c..0000000
--- a/debian/control
+++ /dev/null
@@ -1,27 +0,0 @@
-Source: r-bioc-savr
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: gnu-r
-Priority: optional
-Build-Depends: debhelper (>= 9),
-               dh-r,
-               r-base-dev,
-               r-cran-ggplot2,
-               r-cran-reshape2,
-               r-cran-scales,
-               r-cran-gridextra,
-               r-cran-xml
-Standards-Version: 3.9.8
-Vcs-Browser: https://anonscm.debian.org/viewvc/debian-med/trunk/packages/R/r-bioc-savr/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/R/r-bioc-savr/trunk/
-Homepage: https://bioconductor.org/packages/savR/
-
-Package: r-bioc-savr
-Architecture: all
-Depends: ${R:Depends},
-         ${misc:Depends}
-Recommends: ${R:Recommends}
-Suggests: ${R:Suggests}
-Description: GNU R parse and analyze Illumina SAV files
- This BioConductor module enables to parse Illumina Sequence Analysis
- Viewer (SAV) files, access data, and generate QC plots.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 6bc31d3..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,675 +0,0 @@
-Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: savR
-Upstream-Contact: R. Brent Calder <brent.calder at einstein.yu.edu>
-Source: https://bioconductor.org/packages/savR/
-
-Files: *
-Copyright: 2013-2016 R. Brent Calder <brent.calder at einstein.yu.edu>
-License: AGPL-3
-
-Files: debian/*
-Copyright: 2016 Andreas Tille <tille at debian.org>
-License: AGPL-3
-
-License: AGPL-3
-                     GNU AFFERO GENERAL PUBLIC LICENSE
-                        Version 3, 19 November 2007
- . 
-  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
-  Everyone is permitted to copy and distribute verbatim copies
-  of this license document, but changing it is not allowed.
- .
-                             Preamble
- .
-   The GNU Affero General Public License is a free, copyleft license for
- software and other kinds of works, specifically designed to ensure
- cooperation with the community in the case of network server software.
- .
-   The licenses for most software and other practical works are designed
- to take away your freedom to share and change the works.  By contrast,
- our General Public Licenses are intended to guarantee your freedom to
- share and change all versions of a program--to make sure it remains free
- software for all its users.
- .
-   When we speak of free software, we are referring to freedom, not
- price.  Our General Public Licenses are designed to make sure that you
- have the freedom to distribute copies of free software (and charge for
- them if you wish), that you receive source code or can get it if you
- want it, that you can change the software or use pieces of it in new
- free programs, and that you know you can do these things.
- .
-   Developers that use our General Public Licenses protect your rights
- with two steps: (1) assert copyright on the software, and (2) offer
- you this License which gives you legal permission to copy, distribute
- and/or modify the software.
- .
-   A secondary benefit of defending all users' freedom is that
- improvements made in alternate versions of the program, if they
- receive widespread use, become available for other developers to
- incorporate.  Many developers of free software are heartened and
- encouraged by the resulting cooperation.  However, in the case of
- software used on network servers, this result may fail to come about.
- The GNU General Public License permits making a modified version and
- letting the public access it on a server without ever releasing its
- source code to the public.
- .
-   The GNU Affero General Public License is designed specifically to
- ensure that, in such cases, the modified source code becomes available
- to the community.  It requires the operator of a network server to
- provide the source code of the modified version running there to the
- users of that server.  Therefore, public use of a modified version, on
- a publicly accessible server, gives the public access to the source
- code of the modified version.
- .
-   An older license, called the Affero General Public License and
- published by Affero, was designed to accomplish similar goals.  This is
- a different license, not a version of the Affero GPL, but Affero has
- released a new version of the Affero GPL which permits relicensing under
- this license.
- .
-   The precise terms and conditions for copying, distribution and
- modification follow.
- .
-                        TERMS AND CONDITIONS
- .
-   0. Definitions.
- .
-   "This License" refers to version 3 of the GNU Affero General Public License.
- .
-   "Copyright" also means copyright-like laws that apply to other kinds of
- works, such as semiconductor masks.
- .
-   "The Program" refers to any copyrightable work licensed under this
- License.  Each licensee is addressed as "you".  "Licensees" and
- "recipients" may be individuals or organizations.
- .
-   To "modify" a work means to copy from or adapt all or part of the work
- in a fashion requiring copyright permission, other than the making of an
- exact copy.  The resulting work is called a "modified version" of the
- earlier work or a work "based on" the earlier work.
- .
-   A "covered work" means either the unmodified Program or a work based
- on the Program.
- .
-   To "propagate" a work means to do anything with it that, without
- permission, would make you directly or secondarily liable for
- infringement under applicable copyright law, except executing it on a
- computer or modifying a private copy.  Propagation includes copying,
- distribution (with or without modification), making available to the
- public, and in some countries other activities as well.
- .
-   To "convey" a work means any kind of propagation that enables other
- parties to make or receive copies.  Mere interaction with a user through
- a computer network, with no transfer of a copy, is not conveying.
- .
-   An interactive user interface displays "Appropriate Legal Notices"
- to the extent that it includes a convenient and prominently visible
- feature that (1) displays an appropriate copyright notice, and (2)
- tells the user that there is no warranty for the work (except to the
- extent that warranties are provided), that licensees may convey the
- work under this License, and how to view a copy of this License.  If
- the interface presents a list of user commands or options, such as a
- menu, a prominent item in the list meets this criterion.
- .
-   1. Source Code.
- .
-   The "source code" for a work means the preferred form of the work
- for making modifications to it.  "Object code" means any non-source
- form of a work.
- .
-   A "Standard Interface" means an interface that either is an official
- standard defined by a recognized standards body, or, in the case of
- interfaces specified for a particular programming language, one that
- is widely used among developers working in that language.
- .
-   The "System Libraries" of an executable work include anything, other
- than the work as a whole, that (a) is included in the normal form of
- packaging a Major Component, but which is not part of that Major
- Component, and (b) serves only to enable use of the work with that
- Major Component, or to implement a Standard Interface for which an
- implementation is available to the public in source code form.  A
- "Major Component", in this context, means a major essential component
- (kernel, window system, and so on) of the specific operating system
- (if any) on which the executable work runs, or a compiler used to
- produce the work, or an object code interpreter used to run it.
- .
-   The "Corresponding Source" for a work in object code form means all
- the source code needed to generate, install, and (for an executable
- work) run the object code and to modify the work, including scripts to
- control those activities.  However, it does not include the work's
- System Libraries, or general-purpose tools or generally available free
- programs which are used unmodified in performing those activities but
- which are not part of the work.  For example, Corresponding Source
- includes interface definition files associated with source files for
- the work, and the source code for shared libraries and dynamically
- linked subprograms that the work is specifically designed to require,
- such as by intimate data communication or control flow between those
- subprograms and other parts of the work.
- .
-   The Corresponding Source need not include anything that users
- can regenerate automatically from other parts of the Corresponding
- Source.
- .
-   The Corresponding Source for a work in source code form is that
- same work.
- .
-   2. Basic Permissions.
- .
-   All rights granted under this License are granted for the term of
- copyright on the Program, and are irrevocable provided the stated
- conditions are met.  This License explicitly affirms your unlimited
- permission to run the unmodified Program.  The output from running a
- covered work is covered by this License only if the output, given its
- content, constitutes a covered work.  This License acknowledges your
- rights of fair use or other equivalent, as provided by copyright law.
- .
-   You may make, run and propagate covered works that you do not
- convey, without conditions so long as your license otherwise remains
- in force.  You may convey covered works to others for the sole purpose
- of having them make modifications exclusively for you, or provide you
- with facilities for running those works, provided that you comply with
- the terms of this License in conveying all material for which you do
- not control copyright.  Those thus making or running the covered works
- for you must do so exclusively on your behalf, under your direction
- and control, on terms that prohibit them from making any copies of
- your copyrighted material outside their relationship with you.
- .
-   Conveying under any other circumstances is permitted solely under
- the conditions stated below.  Sublicensing is not allowed; section 10
- makes it unnecessary.
- .
-   3. Protecting Users' Legal Rights From Anti-Circumvention Law.
- .
-   No covered work shall be deemed part of an effective technological
- measure under any applicable law fulfilling obligations under article
- 11 of the WIPO copyright treaty adopted on 20 December 1996, or
- similar laws prohibiting or restricting circumvention of such
- measures.
- .
-   When you convey a covered work, you waive any legal power to forbid
- circumvention of technological measures to the extent such circumvention
- is effected by exercising rights under this License with respect to
- the covered work, and you disclaim any intention to limit operation or
- modification of the work as a means of enforcing, against the work's
- users, your or third parties' legal rights to forbid circumvention of
- technological measures.
- .
-   4. Conveying Verbatim Copies.
- .
-   You may convey verbatim copies of the Program's source code as you
- receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy an appropriate copyright notice;
- keep intact all notices stating that this License and any
- non-permissive terms added in accord with section 7 apply to the code;
- keep intact all notices of the absence of any warranty; and give all
- recipients a copy of this License along with the Program.
- .
-   You may charge any price or no price for each copy that you convey,
- and you may offer support or warranty protection for a fee.
- .
-   5. Conveying Modified Source Versions.
- .
-   You may convey a work based on the Program, or the modifications to
- produce it from the Program, in the form of source code under the
- terms of section 4, provided that you also meet all of these conditions:
- .
-     a) The work must carry prominent notices stating that you modified
-     it, and giving a relevant date.
- .
-     b) The work must carry prominent notices stating that it is
-     released under this License and any conditions added under section
-     7.  This requirement modifies the requirement in section 4 to
-     "keep intact all notices".
- .
-     c) You must license the entire work, as a whole, under this
-     License to anyone who comes into possession of a copy.  This
-     License will therefore apply, along with any applicable section 7
-     additional terms, to the whole of the work, and all its parts,
-     regardless of how they are packaged.  This License gives no
-     permission to license the work in any other way, but it does not
-     invalidate such permission if you have separately received it.
- .
-     d) If the work has interactive user interfaces, each must display
-     Appropriate Legal Notices; however, if the Program has interactive
-     interfaces that do not display Appropriate Legal Notices, your
-     work need not make them do so.
- .
-   A compilation of a covered work with other separate and independent
- works, which are not by their nature extensions of the covered work,
- and which are not combined with it such as to form a larger program,
- in or on a volume of a storage or distribution medium, is called an
- "aggregate" if the compilation and its resulting copyright are not
- used to limit the access or legal rights of the compilation's users
- beyond what the individual works permit.  Inclusion of a covered work
- in an aggregate does not cause this License to apply to the other
- parts of the aggregate.
- .
-   6. Conveying Non-Source Forms.
- .
-   You may convey a covered work in object code form under the terms
- of sections 4 and 5, provided that you also convey the
- machine-readable Corresponding Source under the terms of this License,
- in one of these ways:
- .
-     a) Convey the object code in, or embodied in, a physical product
-     (including a physical distribution medium), accompanied by the
-     Corresponding Source fixed on a durable physical medium
-     customarily used for software interchange.
- .
-     b) Convey the object code in, or embodied in, a physical product
-     (including a physical distribution medium), accompanied by a
-     written offer, valid for at least three years and valid for as
-     long as you offer spare parts or customer support for that product
-     model, to give anyone who possesses the object code either (1) a
-     copy of the Corresponding Source for all the software in the
-     product that is covered by this License, on a durable physical
-     medium customarily used for software interchange, for a price no
-     more than your reasonable cost of physically performing this
-     conveying of source, or (2) access to copy the
-     Corresponding Source from a network server at no charge.
- .
-     c) Convey individual copies of the object code with a copy of the
-     written offer to provide the Corresponding Source.  This
-     alternative is allowed only occasionally and noncommercially, and
-     only if you received the object code with such an offer, in accord
-     with subsection 6b.
- .
-     d) Convey the object code by offering access from a designated
-     place (gratis or for a charge), and offer equivalent access to the
-     Corresponding Source in the same way through the same place at no
-     further charge.  You need not require recipients to copy the
-     Corresponding Source along with the object code.  If the place to
-     copy the object code is a network server, the Corresponding Source
-     may be on a different server (operated by you or a third party)
-     that supports equivalent copying facilities, provided you maintain
-     clear directions next to the object code saying where to find the
-     Corresponding Source.  Regardless of what server hosts the
-     Corresponding Source, you remain obligated to ensure that it is
-     available for as long as needed to satisfy these requirements.
- .
-     e) Convey the object code using peer-to-peer transmission, provided
-     you inform other peers where the object code and Corresponding
-     Source of the work are being offered to the general public at no
-     charge under subsection 6d.
- .
-   A separable portion of the object code, whose source code is excluded
- from the Corresponding Source as a System Library, need not be
- included in conveying the object code work.
- .
-   A "User Product" is either (1) a "consumer product", which means any
- tangible personal property which is normally used for personal, family,
- or household purposes, or (2) anything designed or sold for incorporation
- into a dwelling.  In determining whether a product is a consumer product,
- doubtful cases shall be resolved in favor of coverage.  For a particular
- product received by a particular user, "normally used" refers to a
- typical or common use of that class of product, regardless of the status
- of the particular user or of the way in which the particular user
- actually uses, or expects or is expected to use, the product.  A product
- is a consumer product regardless of whether the product has substantial
- commercial, industrial or non-consumer uses, unless such uses represent
- the only significant mode of use of the product.
- .
-   "Installation Information" for a User Product means any methods,
- procedures, authorization keys, or other information required to install
- and execute modified versions of a covered work in that User Product from
- a modified version of its Corresponding Source.  The information must
- suffice to ensure that the continued functioning of the modified object
- code is in no case prevented or interfered with solely because
- modification has been made.
- .
-   If you convey an object code work under this section in, or with, or
- specifically for use in, a User Product, and the conveying occurs as
- part of a transaction in which the right of possession and use of the
- User Product is transferred to the recipient in perpetuity or for a
- fixed term (regardless of how the transaction is characterized), the
- Corresponding Source conveyed under this section must be accompanied
- by the Installation Information.  But this requirement does not apply
- if neither you nor any third party retains the ability to install
- modified object code on the User Product (for example, the work has
- been installed in ROM).
- .
-   The requirement to provide Installation Information does not include a
- requirement to continue to provide support service, warranty, or updates
- for a work that has been modified or installed by the recipient, or for
- the User Product in which it has been modified or installed.  Access to a
- network may be denied when the modification itself materially and
- adversely affects the operation of the network or violates the rules and
- protocols for communication across the network.
- .
-   Corresponding Source conveyed, and Installation Information provided,
- in accord with this section must be in a format that is publicly
- documented (and with an implementation available to the public in
- source code form), and must require no special password or key for
- unpacking, reading or copying.
- .
-   7. Additional Terms.
- .
-   "Additional permissions" are terms that supplement the terms of this
- License by making exceptions from one or more of its conditions.
- Additional permissions that are applicable to the entire Program shall
- be treated as though they were included in this License, to the extent
- that they are valid under applicable law.  If additional permissions
- apply only to part of the Program, that part may be used separately
- under those permissions, but the entire Program remains governed by
- this License without regard to the additional permissions.
- .
-   When you convey a copy of a covered work, you may at your option
- remove any additional permissions from that copy, or from any part of
- it.  (Additional permissions may be written to require their own
- removal in certain cases when you modify the work.)  You may place
- additional permissions on material, added by you to a covered work,
- for which you have or can give appropriate copyright permission.
- .
-   Notwithstanding any other provision of this License, for material you
- add to a covered work, you may (if authorized by the copyright holders of
- that material) supplement the terms of this License with terms:
- .
-     a) Disclaiming warranty or limiting liability differently from the
-     terms of sections 15 and 16 of this License; or
- .
-     b) Requiring preservation of specified reasonable legal notices or
-     author attributions in that material or in the Appropriate Legal
-     Notices displayed by works containing it; or
- .
-     c) Prohibiting misrepresentation of the origin of that material, or
-     requiring that modified versions of such material be marked in
-     reasonable ways as different from the original version; or
- .
-     d) Limiting the use for publicity purposes of names of licensors or
-     authors of the material; or
- .
-     e) Declining to grant rights under trademark law for use of some
-     trade names, trademarks, or service marks; or
- .
-     f) Requiring indemnification of licensors and authors of that
-     material by anyone who conveys the material (or modified versions of
-     it) with contractual assumptions of liability to the recipient, for
-     any liability that these contractual assumptions directly impose on
-     those licensors and authors.
- .
-   All other non-permissive additional terms are considered "further
- restrictions" within the meaning of section 10.  If the Program as you
- received it, or any part of it, contains a notice stating that it is
- governed by this License along with a term that is a further
- restriction, you may remove that term.  If a license document contains
- a further restriction but permits relicensing or conveying under this
- License, you may add to a covered work material governed by the terms
- of that license document, provided that the further restriction does
- not survive such relicensing or conveying.
- .
-   If you add terms to a covered work in accord with this section, you
- must place, in the relevant source files, a statement of the
- additional terms that apply to those files, or a notice indicating
- where to find the applicable terms.
- .
-   Additional terms, permissive or non-permissive, may be stated in the
- form of a separately written license, or stated as exceptions;
- the above requirements apply either way.
- .
-   8. Termination.
- .
-   You may not propagate or modify a covered work except as expressly
- provided under this License.  Any attempt otherwise to propagate or
- modify it is void, and will automatically terminate your rights under
- this License (including any patent licenses granted under the third
- paragraph of section 11).
- .
-   However, if you cease all violation of this License, then your
- license from a particular copyright holder is reinstated (a)
- provisionally, unless and until the copyright holder explicitly and
- finally terminates your license, and (b) permanently, if the copyright
- holder fails to notify you of the violation by some reasonable means
- prior to 60 days after the cessation.
- .
-   Moreover, your license from a particular copyright holder is
- reinstated permanently if the copyright holder notifies you of the
- violation by some reasonable means, this is the first time you have
- received notice of violation of this License (for any work) from that
- copyright holder, and you cure the violation prior to 30 days after
- your receipt of the notice.
- .
-   Termination of your rights under this section does not terminate the
- licenses of parties who have received copies or rights from you under
- this License.  If your rights have been terminated and not permanently
- reinstated, you do not qualify to receive new licenses for the same
- material under section 10.
- .
-   9. Acceptance Not Required for Having Copies.
- .
-   You are not required to accept this License in order to receive or
- run a copy of the Program.  Ancillary propagation of a covered work
- occurring solely as a consequence of using peer-to-peer transmission
- to receive a copy likewise does not require acceptance.  However,
- nothing other than this License grants you permission to propagate or
- modify any covered work.  These actions infringe copyright if you do
- not accept this License.  Therefore, by modifying or propagating a
- covered work, you indicate your acceptance of this License to do so.
- .
-   10. Automatic Licensing of Downstream Recipients.
- .
-   Each time you convey a covered work, the recipient automatically
- receives a license from the original licensors, to run, modify and
- propagate that work, subject to this License.  You are not responsible
- for enforcing compliance by third parties with this License.
- .
-   An "entity transaction" is a transaction transferring control of an
- organization, or substantially all assets of one, or subdividing an
- organization, or merging organizations.  If propagation of a covered
- work results from an entity transaction, each party to that
- transaction who receives a copy of the work also receives whatever
- licenses to the work the party's predecessor in interest had or could
- give under the previous paragraph, plus a right to possession of the
- Corresponding Source of the work from the predecessor in interest, if
- the predecessor has it or can get it with reasonable efforts.
- .
-   You may not impose any further restrictions on the exercise of the
- rights granted or affirmed under this License.  For example, you may
- not impose a license fee, royalty, or other charge for exercise of
- rights granted under this License, and you may not initiate litigation
- (including a cross-claim or counterclaim in a lawsuit) alleging that
- any patent claim is infringed by making, using, selling, offering for
- sale, or importing the Program or any portion of it.
- .
-   11. Patents.
- .
-   A "contributor" is a copyright holder who authorizes use under this
- License of the Program or a work on which the Program is based.  The
- work thus licensed is called the contributor's "contributor version".
- .
-   A contributor's "essential patent claims" are all patent claims
- owned or controlled by the contributor, whether already acquired or
- hereafter acquired, that would be infringed by some manner, permitted
- by this License, of making, using, or selling its contributor version,
- but do not include claims that would be infringed only as a
- consequence of further modification of the contributor version.  For
- purposes of this definition, "control" includes the right to grant
- patent sublicenses in a manner consistent with the requirements of
- this License.
- .
-   Each contributor grants you a non-exclusive, worldwide, royalty-free
- patent license under the contributor's essential patent claims, to
- make, use, sell, offer for sale, import and otherwise run, modify and
- propagate the contents of its contributor version.
- .
-   In the following three paragraphs, a "patent license" is any express
- agreement or commitment, however denominated, not to enforce a patent
- (such as an express permission to practice a patent or covenant not to
- sue for patent infringement).  To "grant" such a patent license to a
- party means to make such an agreement or commitment not to enforce a
- patent against the party.
- .
-   If you convey a covered work, knowingly relying on a patent license,
- and the Corresponding Source of the work is not available for anyone
- to copy, free of charge and under the terms of this License, through a
- publicly available network server or other readily accessible means,
- then you must either (1) cause the Corresponding Source to be so
- available, or (2) arrange to deprive yourself of the benefit of the
- patent license for this particular work, or (3) arrange, in a manner
- consistent with the requirements of this License, to extend the patent
- license to downstream recipients.  "Knowingly relying" means you have
- actual knowledge that, but for the patent license, your conveying the
- covered work in a country, or your recipient's use of the covered work
- in a country, would infringe one or more identifiable patents in that
- country that you have reason to believe are valid.
- .
-   If, pursuant to or in connection with a single transaction or
- arrangement, you convey, or propagate by procuring conveyance of, a
- covered work, and grant a patent license to some of the parties
- receiving the covered work authorizing them to use, propagate, modify
- or convey a specific copy of the covered work, then the patent license
- you grant is automatically extended to all recipients of the covered
- work and works based on it.
- .
-   A patent license is "discriminatory" if it does not include within
- the scope of its coverage, prohibits the exercise of, or is
- conditioned on the non-exercise of one or more of the rights that are
- specifically granted under this License.  You may not convey a covered
- work if you are a party to an arrangement with a third party that is
- in the business of distributing software, under which you make payment
- to the third party based on the extent of your activity of conveying
- the work, and under which the third party grants, to any of the
- parties who would receive the covered work from you, a discriminatory
- patent license (a) in connection with copies of the covered work
- conveyed by you (or copies made from those copies), or (b) primarily
- for and in connection with specific products or compilations that
- contain the covered work, unless you entered into that arrangement,
- or that patent license was granted, prior to 28 March 2007.
- .
-   Nothing in this License shall be construed as excluding or limiting
- any implied license or other defenses to infringement that may
- otherwise be available to you under applicable patent law.
- .
-   12. No Surrender of Others' Freedom.
- .
-   If conditions are imposed on you (whether by court order, agreement or
- otherwise) that contradict the conditions of this License, they do not
- excuse you from the conditions of this License.  If you cannot convey a
- covered work so as to satisfy simultaneously your obligations under this
- License and any other pertinent obligations, then as a consequence you may
- not convey it at all.  For example, if you agree to terms that obligate you
- to collect a royalty for further conveying from those to whom you convey
- the Program, the only way you could satisfy both those terms and this
- License would be to refrain entirely from conveying the Program.
- .
-   13. Remote Network Interaction; Use with the GNU General Public License.
- .
-   Notwithstanding any other provision of this License, if you modify the
- Program, your modified version must prominently offer all users
- interacting with it remotely through a computer network (if your version
- supports such interaction) an opportunity to receive the Corresponding
- Source of your version by providing access to the Corresponding Source
- from a network server at no charge, through some standard or customary
- means of facilitating copying of software.  This Corresponding Source
- shall include the Corresponding Source for any work covered by version 3
- of the GNU General Public License that is incorporated pursuant to the
- following paragraph.
- .
-   Notwithstanding any other provision of this License, you have
- permission to link or combine any covered work with a work licensed
- under version 3 of the GNU General Public License into a single
- combined work, and to convey the resulting work.  The terms of this
- License will continue to apply to the part which is the covered work,
- but the work with which it is combined will remain governed by version
- 3 of the GNU General Public License.
- .
-   14. Revised Versions of this License.
- .
-   The Free Software Foundation may publish revised and/or new versions of
- the GNU Affero General Public License from time to time.  Such new versions
- will be similar in spirit to the present version, but may differ in detail to
- address new problems or concerns.
- .
-   Each version is given a distinguishing version number.  If the
- Program specifies that a certain numbered version of the GNU Affero General
- Public License "or any later version" applies to it, you have the
- option of following the terms and conditions either of that numbered
- version or of any later version published by the Free Software
- Foundation.  If the Program does not specify a version number of the
- GNU Affero General Public License, you may choose any version ever published
- by the Free Software Foundation.
- .
-   If the Program specifies that a proxy can decide which future
- versions of the GNU Affero General Public License can be used, that proxy's
- public statement of acceptance of a version permanently authorizes you
- to choose that version for the Program.
- .
-   Later license versions may give you additional or different
- permissions.  However, no additional obligations are imposed on any
- author or copyright holder as a result of your choosing to follow a
- later version.
- .
-   15. Disclaimer of Warranty.
- .
-   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
- APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
- HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
- OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
- IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
- ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- .
-   16. Limitation of Liability.
- .
-   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
- THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
- GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
- PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
- EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGES.
- .
-   17. Interpretation of Sections 15 and 16.
- .
-   If the disclaimer of warranty and limitation of liability provided
- above cannot be given local legal effect according to their terms,
- reviewing courts shall apply local law that most closely approximates
- an absolute waiver of all civil liability in connection with the
- Program, unless a warranty or assumption of liability accompanies a
- copy of the Program in return for a fee.
- .
-                      END OF TERMS AND CONDITIONS
- .
-             How to Apply These Terms to Your New Programs
- .
-   If you develop a new program, and you want it to be of the greatest
- possible use to the public, the best way to achieve this is to make it
- free software which everyone can redistribute and change under these terms.
- .
-   To do so, attach the following notices to the program.  It is safest
- to attach them to the start of each source file to most effectively
- state the exclusion of warranty; and each file should have at least
- the "copyright" line and a pointer to where the full notice is found.
- .
-     <one line to give the program's name and a brief idea of what it does.>
-     Copyright (C) <year>  <name of author>
- .
-     This program is free software: you can redistribute it and/or modify
-     it under the terms of the GNU Affero General Public License as published by
-     the Free Software Foundation, either version 3 of the License, or
-     (at your option) any later version.
- .
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-     GNU Affero General Public License for more details.
- .
-     You should have received a copy of the GNU Affero General Public License
-     along with this program.  If not, see <http://www.gnu.org/licenses/>.
- .
- Also add information on how to contact you by electronic and paper mail.
- .
-   If your software can interact with users remotely through a computer
- network, you should also make sure that it provides a way for users to
- get its source.  For example, if your program is a web application, its
- interface could display a "Source" link that leads users to an archive
- of the code.  There are many ways you could offer source, and different
- solutions will be better for different programs; see section 13 for the
- specific requirements.
- .
-   You should also get your employer (if you work as a programmer) or school,
- if any, to sign a "copyright disclaimer" for the program, if necessary.
- For more information on this, and how to apply and follow the GNU AGPL, see
- <http://www.gnu.org/licenses/>.
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 960011c..0000000
--- a/debian/docs
+++ /dev/null
@@ -1,3 +0,0 @@
-tests
-debian/README.test
-debian/tests/run-unit-test
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 7ccf859..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/make -f
-
-%:
-	dh $@ --buildsystem R
-
-override_dh_fixperms:
-	dh_fixperms
-	find debian -name "*.bin" -exec chmod -x \{\} \;
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
deleted file mode 100644
index b044b0c..0000000
--- a/debian/tests/control
+++ /dev/null
@@ -1,3 +0,0 @@
-Tests: run-unit-test
-Depends: @, r-cran-testthat
-Restrictions: allow-stderr
diff --git a/debian/tests/run-unit-test b/debian/tests/run-unit-test
deleted file mode 100644
index 4db5897..0000000
--- a/debian/tests/run-unit-test
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh -e
-
-oname=savR
-pkg=r-bioc-`echo $oname | tr '[A-Z]' '[a-z]'`
-
-if [ "$ADTTMP" = "" ] ; then
-  ADTTMP=`mktemp -d /tmp/${pkg}-test.XXXXXX`
-  trap "rm -rf $ADTTMP" 0 INT QUIT ABRT PIPE TERM
-fi
-cd $ADTTMP
-cp -a /usr/share/doc/${pkg}/tests/* $ADTTMP
-LC_ALL=C R --no-save < testthat.R
-rm -fr $ADTTMP/*
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index b44dfa8..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,3 +0,0 @@
-version=3
-opts=downloadurlmangle=s?^(.*)\.\.?http:$1packages/release/bioc? \
- http://www.bioconductor.org/packages/release/bioc/html/savR.html .*/savR_([\d\.]+)\.tar\.gz
diff --git a/inst/doc/savR.R b/inst/doc/savR.R
new file mode 100644
index 0000000..0d26068
--- /dev/null
+++ b/inst/doc/savR.R
@@ -0,0 +1,101 @@
+### R code from vignette source 'savR.Rnw'
+
+###################################################
+### code chunk number 1: prepare
+###################################################
+library(savR)
+
+
+###################################################
+### code chunk number 2: intro
+###################################################
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+
+
+###################################################
+### code chunk number 3: show
+###################################################
+fc
+
+
+###################################################
+### code chunk number 4: doPfPlot (eval = FALSE)
+###################################################
+## pfBoxplot(fc)
+
+
+###################################################
+### code chunk number 5: pfPlot
+###################################################
+png(filename="pf.png", width=400, height=300, res=72)
+pfBoxplot(fc)
+invisible(dev.off())
+
+
+###################################################
+### code chunk number 6: intro2 (eval = FALSE)
+###################################################
+## fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+
+
+###################################################
+### code chunk number 7: ri
+###################################################
+directions(fc)
+reads(fc)
+cycles(fc)
+flowcellLayout(fc)
+
+
+###################################################
+### code chunk number 8: ciex
+###################################################
+head(correctedIntensities(fc), n=1)
+
+
+###################################################
+### code chunk number 9: doCiPlot (eval = FALSE)
+###################################################
+## plotIntensity(fc)
+
+
+###################################################
+### code chunk number 10: ciPlot
+###################################################
+png(filename="ci.png", width=250, height=400, res=72)
+plotIntensity(fc)
+invisible(dev.off())
+
+
+###################################################
+### code chunk number 11: qmex
+###################################################
+head(qualityMetrics(fc), n=1)
+
+
+###################################################
+### code chunk number 12: doQhPlot (eval = FALSE)
+###################################################
+## qualityHeatmap(fc,1,1)
+
+
+###################################################
+### code chunk number 13: qhPlot
+###################################################
+png(filename="qh.png", width=400, height=300, res=72)
+qualityHeatmap(fc,1,1)
+invisible(dev.off())
+
+
+###################################################
+### code chunk number 14: tmex
+###################################################
+head(tileMetrics(fc), n=4)
+
+
+###################################################
+### code chunk number 15: example2
+###################################################
+head(extractionMetrics(fc), n=1)
+
+
diff --git a/inst/doc/savR.Rnw b/inst/doc/savR.Rnw
new file mode 100644
index 0000000..45faad9
--- /dev/null
+++ b/inst/doc/savR.Rnw
@@ -0,0 +1,196 @@
+\documentclass[letterpaper,11pt,oneside,final,onecolumn,article]{memoir}
+\usepackage{microtype}
+\usepackage{helvet}
+\usepackage{pxfonts}
+\usepackage{eulervm}
+\usepackage{nicefrac}
+\usepackage{graphicx}
+\usepackage{textcomp}
+\usepackage[numbers,square,comma,sort&compress]{natbib}
+\usepackage{soul, color, ulem} % underline, overstrike, highlight 
+\usepackage{amssymb}
+\usepackage{hyperref} % URL's
+\usepackage{memhfixc} % should have loaded already, memoir bugs
+
+\setlrmarginsandblock{.75in}{.75in}{1}
+\setulmarginsandblock{.75in}{.75in}{1}
+\checkandfixthelayout
+
+\pagestyle{empty}
+
+\renewcommand{\abstractname}{} % no ``abstract''
+\renewcommand{\bibname}{} % no ``bibliography''
+
+\setsecheadstyle{\Large\sffamily\raggedright}
+\setsubsecheadstyle{\large\sffamily\raggedright}
+\setsubsubsecheadstyle{\normalsize\sffamily\raggedright}
+
+%\VignetteIndexEntry{Using savR}
+
+\begin{document}
+
+\fvset{listparameters={\setlength{\topsep}{0pt}}} 
+\renewenvironment{Schunk}{\vspace{\topsep}}{\vspace{\topsep}} 
+\renewenvironment{Schunk}{\vspace{5pt}}{\vspace{5pt}} 
+
+\title{Using savR}
+\author{R. Brent Calder}
+
+\maketitle
+
+<<prepare>>=
+library(savR)
+@
+
+<<intro,cache=T>>=
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+@
+
+<<show>>=
+fc
+@
+
+<<doPfPlot,eval=F>>=
+pfBoxplot(fc)
+@
+<<pfPlot,echo=F>>=
+png(filename="pf.png", width=400, height=300, res=72)
+pfBoxplot(fc)
+invisible(dev.off())
+@
+
+\begin{figure}[htb]
+\begin{center}
+\includegraphics[width=3in]{pf.png}
+\end{center}
+\caption{Boxplot of total vs. PF clusters}
+\label{fig:fp}
+\end{figure}
+
+\section*{Introduction}
+
+The Illumina Sequence Analysis Viewer (SAV) is a Windows application provided by Illumina that 
+presents graphs made in real time from data collected over the course of basecalling.  This data was 
+previously also made available in HTML format for inspection after the run; however, it is now
+preserved in binary format and not simply parsed by users who wish to perform automated quality
+assessment.  Here is presented \textit{savR}, an R package to parse the binary output, generate 
+QC assessment plots and make the data available to users of Illumina sequencing instruments.
+For more information about Illumina SAV, please consult the Illumina iCom website and the
+Sequencing Analysis Viewer User's Guide, available
+\href{https://duckduckgo.com/?q=sequencing%20analysis%20viewer%20user%27s%20guide}{\textit{online}}.
+
+\section*{Description}
+
+The \texttt{savR} function is passed a path to an Illumina HiSeq or MiSeq run, and returns a
+\texttt{savProject} object, containing the parsed data.  Accessor methods are available for
+information in the \texttt{RunInfo.xml} file as well as the parsed SAV Metrics files.  These include
+corrected intensities, quality metrics, tile metrics, and extraction metrics.  The \textit{savR}
+package comes with an example MiSeq data set which can be loaded thusly:
+
+<<intro2,eval=F>>=
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+@
+
+\subsection*{RunInfo.xml}
+
+The \texttt{RunInfo.xml} file is parsed and stored in the slots of the \texttt{savProject} object.
+There are accessor methods for the project's \texttt{location}, \texttt{reads}, number of ``ends'' 
+or \texttt{directions}, the \texttt{run} ID, the number of \texttt{cycles}, and a description of
+the \texttt{flowcellLayout}.
+
+<<ri>>=
+directions(fc)
+reads(fc)
+cycles(fc)
+flowcellLayout(fc)
+@
+
+\subsection*{Corrected intensitites}
+
+Corrected intensity metrics (obtained from \texttt{CorrectedIntMetricsOut.bin}) can be inspected
+by the \texttt{correctedIntestites} accessor method:
+
+<<ciex>>=
+head(correctedIntensities(fc), n=1)
+@
+
+This is a \texttt{data.frame} of intensity metrics; one line for each set of lane, tile and cycle 
+measurements. Reported statistics include average intensity, corrected intensity (for cross-talk between 
+bases and phasing/pre-phasing), called corrected intensities, number of called bases and signal to
+noise ratio.  There are methods which act upon \texttt{savProject} objects to produce QC plots, for example 
+plotIntensity to assess signal intensity for each channel as in figure \ref{fig:ci}.
+
+<<doCiPlot,eval=F>>=
+plotIntensity(fc)
+@
+
+<<ciPlot,echo=F>>=
+png(filename="ci.png", width=250, height=400, res=72)
+plotIntensity(fc)
+invisible(dev.off())
+@
+
+\begin{figure}[htb]
+\begin{center}
+\includegraphics[width=2.25in]{ci.png}
+\end{center}
+\caption{Corrected intensity plot: cycle 1, base ``A''.}
+\label{fig:ci}
+\end{figure}
+
+\subsection*{Quality Metrics}
+
+The quality metrics (\texttt{QMetricsOut.bin}) file contains per-lane/tile/cycle metrics for the number
+of clusters with quality at each PHRED value from 1-50.
+
+
+<<qmex>>=
+head(qualityMetrics(fc), n=1)
+@
+
+<<doQhPlot,eval=F>>=
+qualityHeatmap(fc,1,1)
+@
+
+<<qhPlot,echo=F>>=
+png(filename="qh.png", width=400, height=300, res=72)
+qualityHeatmap(fc,1,1)
+invisible(dev.off())
+@
+
+\begin{figure}[h]
+\begin{center}
+\includegraphics[width=3.5in]{qh.png}
+\end{center}
+\caption{Quality heatmap: lane 1, read 1.}
+\label{fig:qh}
+\end{figure}
+
+\subsection*{Tile Metrics}
+
+The tile metrics (\texttt{TileMetricsOut.bin}) file contains coded information about per-lane/cycle/tile cluster density,
+pass-filter clusters, phasing and pre-phasing data.  Consult the \texttt{tileMetrics} help page for more information.
+
+<<tmex>>=
+head(tileMetrics(fc), n=4)
+@
+
+\subsection*{Extraction Metrics}
+
+The extraction metrics (\texttt{ExtractionMetricsOut.bin}) file contains per-lane/cycle/tile information about per-base FWHM
+(full width pixel size of clusters at half maximum) and 90th \%-ile intensity of signal intensity.
+
+<<example2>>=
+head(extractionMetrics(fc), n=1)
+@
+
+\section*{Coda}
+
+There is a convenience function (\texttt{buildReports}), which partially reconstructs the Illumina reports folder
+that was previously generated by the Illumina instrument software and which was superseded by SAV and InterOp files.
+
+
+
+
+
+\end{document}
diff --git a/inst/doc/savR.pdf b/inst/doc/savR.pdf
new file mode 100644
index 0000000..9d3af16
Binary files /dev/null and b/inst/doc/savR.pdf differ
diff --git a/inst/extdata/MiSeq/InterOp/CorrectedIntMetricsOut.bin b/inst/extdata/MiSeq/InterOp/CorrectedIntMetricsOut.bin
new file mode 100755
index 0000000..dbd918d
Binary files /dev/null and b/inst/extdata/MiSeq/InterOp/CorrectedIntMetricsOut.bin differ
diff --git a/inst/extdata/MiSeq/InterOp/ExtractionMetricsOut.bin b/inst/extdata/MiSeq/InterOp/ExtractionMetricsOut.bin
new file mode 100755
index 0000000..f960d0d
Binary files /dev/null and b/inst/extdata/MiSeq/InterOp/ExtractionMetricsOut.bin differ
diff --git a/inst/extdata/MiSeq/InterOp/QMetricsOut.bin b/inst/extdata/MiSeq/InterOp/QMetricsOut.bin
new file mode 100755
index 0000000..3eda106
Binary files /dev/null and b/inst/extdata/MiSeq/InterOp/QMetricsOut.bin differ
diff --git a/inst/extdata/MiSeq/InterOp/TileMetricsOut.bin b/inst/extdata/MiSeq/InterOp/TileMetricsOut.bin
new file mode 100755
index 0000000..6ae758e
Binary files /dev/null and b/inst/extdata/MiSeq/InterOp/TileMetricsOut.bin differ
diff --git a/inst/extdata/MiSeq/RunInfo.xml b/inst/extdata/MiSeq/RunInfo.xml
new file mode 100644
index 0000000..ee5f15c
--- /dev/null
+++ b/inst/extdata/MiSeq/RunInfo.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<RunInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2">
+  <Run Id="131030_M01243_0072_000000000-A58WM" Number="71">
+    <Flowcell>000000000-A58WM</Flowcell>
+    <Instrument>M01243</Instrument>
+    <Date>131030</Date>
+    <Reads>
+      <Read NumCycles="76" Number="1" IsIndexedRead="N" />
+      <Read NumCycles="6" Number="2" IsIndexedRead="Y" />
+    </Reads>
+    <FlowcellLayout LaneCount="1" SurfaceCount="2" SwathCount="1" TileCount="19" />
+  </Run>
+</RunInfo>
\ No newline at end of file
diff --git a/man/buildReports.Rd b/man/buildReports.Rd
new file mode 100644
index 0000000..421422e
--- /dev/null
+++ b/man/buildReports.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{buildReports}
+\alias{buildReports}
+\alias{buildReports,savProject,character-method}
+\alias{buildReports,savProject,missing-method}
+\title{Generate Illumina reports folder}
+\usage{
+buildReports(project, destination)
+
+\S4method{buildReports}{savProject,character}(project,
+  destination = "./savR-reports")
+
+\S4method{buildReports}{savProject,missing}(project)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{destination}{path to save reports folder}
+}
+\description{
+Generate a folder of images that approximates the format of the folder that
+was superceded by InterOp. Requires the Cairo package.
+}
+\examples{
+\dontrun{
+example(savR)
+buildReports(fc, "reports")
+}
+}
+
diff --git a/man/clusterQualityGtN.Rd b/man/clusterQualityGtN.Rd
new file mode 100644
index 0000000..b3a5b95
--- /dev/null
+++ b/man/clusterQualityGtN.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{clusterQualityGtN}
+\alias{clusterQualityGtN}
+\alias{clusterQualityGtN,savProject,integer,integer,integer}
+\alias{clusterQualityGtN,savProject,integer,integer,integer-method}
+\title{Get the proportion of clusters over a specified quality threshold}
+\usage{
+clusterQualityGtN(project, lane, cycle, n)
+
+\S4method{clusterQualityGtN}{savProject,integer,integer,integer}(project, lane,
+  cycle, n = 30L)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{lane}{lane(s) number}
+
+\item{cycle}{cycle(s) number}
+
+\item{n}{quality threshold}
+}
+\description{
+Return the ratio of clusters with a quality score less than or equal to
+a specified value (n) for the requested lanes and cycles.
+}
+\examples{
+\dontrun{
+example(savR)
+clusterQualityGtN(fc, 1L, 25L, 30L)
+}
+}
+
diff --git a/man/clusters.Rd b/man/clusters.Rd
new file mode 100644
index 0000000..0fb3f2e
--- /dev/null
+++ b/man/clusters.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{clusters}
+\alias{clusters}
+\alias{clusters,savProject,integer-method}
+\title{Get number of clusters per lane}
+\usage{
+clusters(project, lane)
+
+\S4method{clusters}{savProject,integer}(project, lane = 1L)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{lane}{lane(s) number}
+}
+\description{
+Sum the total number of clusters for all tiles in the lane.
+}
+\examples{
+\dontrun{
+example(savR)
+clusters(fc, 1L)
+}
+}
+
diff --git a/man/correctedIntensities.Rd b/man/correctedIntensities.Rd
new file mode 100644
index 0000000..4b612db
--- /dev/null
+++ b/man/correctedIntensities.Rd
@@ -0,0 +1,38 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{correctedIntensities}
+\alias{correctedIntensities}
+\alias{correctedIntensities,savProject-method}
+\title{Get Corrected Intensity data}
+\usage{
+correctedIntensities(project)
+
+\S4method{correctedIntensities}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+sorted data.frame of CI data.
+}
+\description{
+Returns a data frame of corrected intensity data.
+}
+\details{
+\describe{
+ \item{\code{lane}:}{Lane number} \cr
+ \item{\code{tile}:}{Tile ID} \cr
+ \item{\code{cycle}:}{Cycle number} \cr
+ \item{\code{avg_intensity}:}{Average intensity} \cr
+ \item{\code{avg_cor_[ACGT]}:}{Average corrected intensity of channel A, C, G, or T} \cr
+ \item{\code{avg_cor_called_[ACGT]}:}{Average corrected intensity for called clusters in channel A, C, G, or T} \cr
+ \item{\code{num_\{none|[ACGT]\}}:}{Number of called bases for no-call, A, C, G, or T} \cr
+ \item{\code{sig_noise}:}{Signal to noise ratio} \cr
+}
+}
+\examples{
+example(savR)
+colnames(correctedIntensities(fc))
+}
+
diff --git a/man/cycles.Rd b/man/cycles.Rd
new file mode 100644
index 0000000..a745f43
--- /dev/null
+++ b/man/cycles.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{cycles}
+\alias{cycles}
+\alias{cycles,savProject-method}
+\title{Get the total number of cycles}
+\usage{
+cycles(project)
+
+\S4method{cycles}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+total number of cycles in run, including all sequencing and index reads.
+}
+\description{
+Accessor to obtain the total number of cycles sequenced in an Illumina sequencing run.
+}
+\examples{
+example(savR)
+cycles(fc)
+}
+
diff --git a/man/directions.Rd b/man/directions.Rd
new file mode 100644
index 0000000..406574b
--- /dev/null
+++ b/man/directions.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{directions}
+\alias{directions}
+\alias{directions,savProject-method}
+\title{Get the number of sequence reads}
+\usage{
+directions(project)
+
+\S4method{directions}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+number of reads
+}
+\description{
+Returns the number of sequencing reads (excluding index reads).
+}
+\examples{
+example(savR)
+directions(fc)
+}
+
diff --git a/man/errorMetrics.Rd b/man/errorMetrics.Rd
new file mode 100644
index 0000000..f140c57
--- /dev/null
+++ b/man/errorMetrics.Rd
@@ -0,0 +1,36 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{errorMetrics}
+\alias{errorMetrics}
+\alias{errorMetrics,savProject-method}
+\title{Get Error Metrics}
+\usage{
+errorMetrics(project)
+
+\S4method{errorMetrics}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+sorted data.frame of Error metrics
+}
+\description{
+Error metrics for lane, tile, and cycle.
+}
+\details{
+\describe{
+ \item{\code{lane}:}{Lane number}
+ \item{\code{tile}:}{Tile ID}
+ \item{\code{cycle}:}{Cycle number}
+ \item{\code{errorrate}:}{Error rate}
+ \item{\code{nPerfect}:}{number of perfect reads}
+ \item{\code{n[1-4]Error}:}{Number of reads with 1, 2, 3 and 4 errors}
+}
+}
+\examples{
+example(savR)
+colnames(extractionMetrics(fc))
+}
+
diff --git a/man/extractionMetrics.Rd b/man/extractionMetrics.Rd
new file mode 100644
index 0000000..b328132
--- /dev/null
+++ b/man/extractionMetrics.Rd
@@ -0,0 +1,36 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{extractionMetrics}
+\alias{extractionMetrics}
+\alias{extractionMetrics,savProject-method}
+\title{Get Extraction Metrics}
+\usage{
+extractionMetrics(project)
+
+\S4method{extractionMetrics}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+sorted data.frame of Extraction metrics
+}
+\description{
+Extraction (intensity and FWHM) metrics for lane, tile, and cycle.
+}
+\details{
+\describe{
+ \item{\code{lane}:}{Lane number}
+ \item{\code{tile}:}{Tile ID}
+ \item{\code{cycle}:}{Cycle number}
+ \item{\code{FWHM_[ACGT]}:}{Full width at half maximum for A, C, G, or T}
+ \item{\code{int_[ACGT]}:}{Intensity of channel A, C, G, or T}
+ \item{\code{datestamp}:}{Time/date stamp}
+}
+}
+\examples{
+example(savR)
+colnames(extractionMetrics(fc))
+}
+
diff --git a/man/flowcellLayout.Rd b/man/flowcellLayout.Rd
new file mode 100644
index 0000000..7c52ed2
--- /dev/null
+++ b/man/flowcellLayout.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{flowcellLayout}
+\alias{flowcellLayout}
+\alias{flowcellLayout,savProject-method}
+\title{Get flowcell layout}
+\usage{
+flowcellLayout(project)
+
+\S4method{flowcellLayout}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+\link{illuminaFlowCellLayout-class} object
+}
+\description{
+Accessor to obtain information about the characteristics of the flowcell
+from an Illumina sequencing run.
+}
+\examples{
+example(savR)
+flowcellLayout(fc)
+}
+
diff --git a/man/illuminaFlowCellLayout-class.Rd b/man/illuminaFlowCellLayout-class.Rd
new file mode 100644
index 0000000..7c45736
--- /dev/null
+++ b/man/illuminaFlowCellLayout-class.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{illuminaFlowCellLayout-class}
+\alias{illuminaFlowCellLayout-class}
+\title{Layout of an Illumina flowcell}
+\description{
+Class representation of the features of an Illumina flow cell.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{lanecount}:}{Number of lanes on the flowcell}
+\item{\code{surfacecount}:}{Number of surfaces}
+\item{\code{swathcount}:}{Number of imaging swaths}
+\item{\code{tilecount}:}{Number of tiles per swath}
+\item{\code{sectionperlane}:}{Number of sections per lane (NextSeq)}
+\item{\code{lanepersection}:}{Number of lanes per section (NextSeq)}
+\item{\code{tilenamingconvention}:}{Description of deviation from original formatting layout}
+}
+}
+
diff --git a/man/illuminaRead-class.Rd b/man/illuminaRead-class.Rd
new file mode 100644
index 0000000..939f5dd
--- /dev/null
+++ b/man/illuminaRead-class.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{illuminaRead-class}
+\alias{illuminaRead-class}
+\title{Illumina read}
+\description{
+Class representation of the features of an Illumina sequencing read.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{number}:}{the index of this read in sequencing}
+\item{\code{cycles}:}{number of cycles in this read}
+\item{\code{index}:}{logical representing whether or not this read is an index read}
+}
+}
+
diff --git a/man/location.Rd b/man/location.Rd
new file mode 100644
index 0000000..5e1bd3b
--- /dev/null
+++ b/man/location.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{location}
+\alias{location}
+\alias{location,savProject-method}
+\title{Get Flowcell folder location}
+\usage{
+location(project)
+
+\S4method{location}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+normalized path to Illumina run data.
+}
+\description{
+Accessor to obtain the path to data for a particular SAV project.
+}
+\examples{
+example(savR)
+location(fc)
+}
+
diff --git a/man/pfBoxplot.Rd b/man/pfBoxplot.Rd
new file mode 100644
index 0000000..51b4dda
--- /dev/null
+++ b/man/pfBoxplot.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{pfBoxplot}
+\alias{pfBoxplot}
+\alias{pfBoxplot,savProject-method}
+\title{PF Boxplot}
+\usage{
+pfBoxplot(project)
+
+\S4method{pfBoxplot}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\description{
+Generate a boxplot of the numbers of clusters and the number of
+Illumina pass-filter clusters per tile and lane
+}
+
diff --git a/man/pfClusters.Rd b/man/pfClusters.Rd
new file mode 100644
index 0000000..0a68095
--- /dev/null
+++ b/man/pfClusters.Rd
@@ -0,0 +1,28 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{pfClusters}
+\alias{pfClusters}
+\alias{pfClusters,savProject,integer}
+\alias{pfClusters,savProject,integer-method}
+\title{Get number of PF clusters per lane}
+\usage{
+pfClusters(project, lane)
+
+\S4method{pfClusters}{savProject,integer}(project, lane = 1L)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{lane}{lane(s) number}
+}
+\description{
+Sum the total pass filter number of clusters for all tiles in the lane.
+}
+\examples{
+\dontrun{
+example(savR)
+pfClusters(fc, 1L)
+}
+}
+
diff --git a/man/plotFWHM.Rd b/man/plotFWHM.Rd
new file mode 100644
index 0000000..c6945de
--- /dev/null
+++ b/man/plotFWHM.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{plotFWHM}
+\alias{plotFWHM}
+\alias{plotFWHM,savProject,integer,character-method}
+\alias{plotFWHM,savProject,integer,missing-method}
+\alias{plotFWHM,savProject,missing,character-method}
+\alias{plotFWHM,savProject,missing,missing-method}
+\title{Generate FWHM plots}
+\usage{
+plotFWHM(project, cycle, base)
+
+\S4method{plotFWHM}{savProject,integer,character}(project, cycle = 1L,
+  base = c("A", "C", "G", "T"))
+
+\S4method{plotFWHM}{savProject,missing,missing}(project)
+
+\S4method{plotFWHM}{savProject,integer,missing}(project, cycle)
+
+\S4method{plotFWHM}{savProject,missing,character}(project, base)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{cycle}{sequence cycle}
+
+\item{base}{nucleotide base (ACGT)}
+}
+\description{
+Plots the average full width of clusters at half maximum (FWHM) of each tile
+for a given cycle and base.
+}
+
diff --git a/man/plotIntensity.Rd b/man/plotIntensity.Rd
new file mode 100644
index 0000000..46a85d0
--- /dev/null
+++ b/man/plotIntensity.Rd
@@ -0,0 +1,33 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{plotIntensity}
+\alias{plotIntensity}
+\alias{plotIntensity,savProject,integer,character-method}
+\alias{plotIntensity,savProject,integer,missing-method}
+\alias{plotIntensity,savProject,missing,character-method}
+\alias{plotIntensity,savProject,missing,missing-method}
+\title{Plot flowcell intensity by base and cycle}
+\usage{
+plotIntensity(project, cycle, base)
+
+\S4method{plotIntensity}{savProject,integer,character}(project, cycle = 1L,
+  base = c("A", "C", "G", "T"))
+
+\S4method{plotIntensity}{savProject,missing,missing}(project)
+
+\S4method{plotIntensity}{savProject,integer,missing}(project, cycle)
+
+\S4method{plotIntensity}{savProject,missing,character}(project, base)
+}
+\arguments{
+\item{project}{A \link{savProject-class} object}
+
+\item{cycle}{integer cycle number}
+
+\item{base}{character for nucleotide}
+}
+\description{
+Draws a representation of a flowcell, showing the average corrected called intensity values.
+}
+
diff --git a/man/plotQGT30.Rd b/man/plotQGT30.Rd
new file mode 100644
index 0000000..3a6000c
--- /dev/null
+++ b/man/plotQGT30.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{plotQGT30}
+\alias{plotQGT30}
+\alias{plotQGT30,savProject,integer-method}
+\alias{plotQGT30,savProject,missing-method}
+\title{Plot Quality > 30 for a flowcell}
+\usage{
+plotQGT30(project, cycle)
+
+\S4method{plotQGT30}{savProject,integer}(project, cycle = 1L)
+
+\S4method{plotQGT30}{savProject,missing}(project)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{cycle}{sequence cycle}
+}
+\description{
+Generate a plot for a given cycle of the percentage of clusters in each tile
+that are >= Q30.
+}
+
diff --git a/man/qualityHeatmap.Rd b/man/qualityHeatmap.Rd
new file mode 100644
index 0000000..8f5ab53
--- /dev/null
+++ b/man/qualityHeatmap.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{qualityHeatmap}
+\alias{qualityHeatmap}
+\alias{qualityHeatmap,savProject,integer,integer,logical-method}
+\alias{qualityHeatmap,savProject,numeric,numeric,missing-method}
+\title{Generate a heatmap of qualities}
+\usage{
+qualityHeatmap(project, lane, read, collapse)
+
+\S4method{qualityHeatmap}{savProject,integer,integer,logical}(project, lane,
+  read, collapse = T)
+
+\S4method{qualityHeatmap}{savProject,numeric,numeric,missing}(project, lane,
+  read)
+}
+\arguments{
+\item{project}{SAV project}
+
+\item{lane}{integer lane specification}
+
+\item{read}{integer vector of sequence reads to include (not including index reads)}
+
+\item{collapse}{whether or not to collapse index reads into the preceeding read (# reads = directions), default TRUE}
+}
+\description{
+Plots a heatmap of quality vs cycle for a given lane for 1 or more sequence reads.  Read qualities include sequence + index.
+}
+
diff --git a/man/qualityMetrics.Rd b/man/qualityMetrics.Rd
new file mode 100644
index 0000000..4914dbe
--- /dev/null
+++ b/man/qualityMetrics.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{qualityMetrics}
+\alias{qualityMetrics}
+\alias{qualityMetrics,savProject-method}
+\title{Get Quality Metrics data}
+\usage{
+qualityMetrics(project)
+
+\S4method{qualityMetrics}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+sorted data.frame of quality data
+}
+\description{
+Quality metric by lane, tile and cycle.
+}
+\details{
+\describe{
+ \item{\code{lane}:}{Lane number}
+ \item{\code{tile}:}{Tile ID}
+ \item{\code{cycle}:}{Cycle number}
+ \item{\code{Q1-Q50}:}{Number of clusters with quality of indicated column}
+}
+}
+\examples{
+example(savR)
+colnames(qualityMetrics(fc))
+}
+
diff --git a/man/reads.Rd b/man/reads.Rd
new file mode 100644
index 0000000..e0613c3
--- /dev/null
+++ b/man/reads.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{reads}
+\alias{reads}
+\alias{reads,savProject-method}
+\title{Get reads}
+\usage{
+reads(project)
+
+\S4method{reads}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+List of \link{illuminaRead-class} objects
+}
+\description{
+Accessor to obtain information about the reads of a particular Illumina
+sequencing run.
+}
+\examples{
+example(savR)
+reads(fc)
+}
+
diff --git a/man/run.Rd b/man/run.Rd
new file mode 100644
index 0000000..9891c3d
--- /dev/null
+++ b/man/run.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{run}
+\alias{run}
+\alias{run,savProject-method}
+\title{Get the Run ID}
+\usage{
+run(project)
+
+\S4method{run}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+parsed Illumina run id
+}
+\description{
+Accessor to obtain the string identifier of an Illumina sequencing run.
+}
+\examples{
+example(savR)
+run(fc)
+}
+
diff --git a/man/savCorrectedIntensityFormat-class.Rd b/man/savCorrectedIntensityFormat-class.Rd
new file mode 100644
index 0000000..281be1c
--- /dev/null
+++ b/man/savCorrectedIntensityFormat-class.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savCorrectedIntensityFormat-class}
+\alias{savCorrectedIntensityFormat-class}
+\title{Corrected Intensity formatter}
+\description{
+Lane, tile, cycle, average intensity, corrected intensities (ACGT),
+average corrected called intensities (ACGT), number of no-calls,
+number of (ACGT) calls, and signal to noise ratio.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+}
+}
+
diff --git a/man/savData-class.Rd b/man/savData-class.Rd
new file mode 100644
index 0000000..e361632
--- /dev/null
+++ b/man/savData-class.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savData-class}
+\alias{savData-class}
+\title{Structure for holding parsed InterOp headers and data}
+\description{
+Structure for holding parsed InterOp headers and data
+}
+\section{Slots}{
+
+\describe{
+\item{\code{header}:}{list of parsed header values}
+\item{\code{data}:}{data.frame of parsed values}
+}
+}
+
diff --git a/man/savErrorFormat-class.Rd b/man/savErrorFormat-class.Rd
new file mode 100644
index 0000000..da8554d
--- /dev/null
+++ b/man/savErrorFormat-class.Rd
@@ -0,0 +1,21 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savErrorFormat-class}
+\alias{savErrorFormat-class}
+\title{Error Metrics formatter}
+\description{
+Lane, tile, cycle, errorrate, nPerfect, n1Error, n2Error,
+n3Error, n4Error.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+}
+}
+
diff --git a/man/savExtractionFormat-class.Rd b/man/savExtractionFormat-class.Rd
new file mode 100644
index 0000000..6ccfaaa
--- /dev/null
+++ b/man/savExtractionFormat-class.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savExtractionFormat-class}
+\alias{savExtractionFormat-class}
+\title{Extraction Metrics formatter}
+\description{
+Lane, tile, cycle, FWHM (ACGT), intensity (ACGT), datestamp, timestamp.
+Datestamp and timestamp are munged at the moment because R does not
+have native support for 32-bit unsigned integers and I have not implemented
+a solution.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+}
+}
+
diff --git a/man/savFormat-class.Rd b/man/savFormat-class.Rd
new file mode 100644
index 0000000..1cf79a2
--- /dev/null
+++ b/man/savFormat-class.Rd
@@ -0,0 +1,22 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savFormat-class}
+\alias{savFormat-class}
+\title{Base class for formatters}
+\description{
+Defines the necessary slots to create parse different binary files using
+the same generic parser.
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+\item{\code{default}:}{logical default format ()}
+}
+}
+
diff --git a/man/savProject-class.Rd b/man/savProject-class.Rd
new file mode 100644
index 0000000..921aa1e
--- /dev/null
+++ b/man/savProject-class.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savProject-class}
+\alias{savProject-class}
+\title{SAV project class}
+\description{
+Represents a flowcell, metadata and parsed SAV information
+}
+\section{Slots}{
+
+\describe{
+\item{\code{location}:}{Full path to flowcell directory}
+\item{\code{reads}:}{List of \link{illuminaRead-class}}
+\item{\code{layout}:}{\link{illuminaFlowCellLayout-class}}
+\item{\code{runid}:}{Run ID}
+\item{\code{number}:}{Run number}
+\item{\code{flowcell}:}{Flowcell ID}
+\item{\code{instrument}:}{Instrument ID}
+\item{\code{date}:}{Run date}
+\item{\code{cycles}:}{Total number of cycles}
+\item{\code{directions}:}{Total number of sequence runs (ends)}
+\item{\code{parsedData}:}{SAV data}
+}
+}
+
diff --git a/man/savQualityFormat-class.Rd b/man/savQualityFormat-class.Rd
new file mode 100644
index 0000000..89e7ea0
--- /dev/null
+++ b/man/savQualityFormat-class.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savQualityFormat-class}
+\alias{savQualityFormat-class}
+\title{Quality Metrics formatter}
+\description{
+Lane, tile, cycle, Q1-Q50 counts
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+}
+}
+
diff --git a/man/savQualityFormatV5-class.Rd b/man/savQualityFormatV5-class.Rd
new file mode 100644
index 0000000..fca927b
--- /dev/null
+++ b/man/savQualityFormatV5-class.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savQualityFormatV5-class}
+\alias{savQualityFormatV5-class}
+\title{Quality Metrics formatter version 5}
+\description{
+Lane, tile, cycle, Q1-Q50 counts
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number}
+}
+}
+
diff --git a/man/savR-package.Rd b/man/savR-package.Rd
new file mode 100644
index 0000000..e7363fa
--- /dev/null
+++ b/man/savR-package.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/savR-package.R
+\docType{package}
+\name{savR-package}
+\alias{savR-package}
+\title{Parse and analyze Illumina SAV files}
+\description{
+Parse Illumina Sequence Analysis Viewer files
+}
+\details{
+\tabular{ll}{
+Package: \tab savR \cr
+Type: \tab Package \cr
+Version: \tab 1.7.5 \cr
+Date: \tab 2015-07-28 \cr
+License: \tab AGPL-3 \cr
+LazyLoad: \tab yes \cr
+}
+
+Parse Illumina Sequence Analysis Viewer (SAV)
+files, access data, and generate QC plots.
+}
+\author{
+R. Brent Calder \email{brent.calder at einstein.yu.edu}
+}
+\references{
+For information about Illumina SAV, please refer to \cr \url{http://supportres.illumina.com/documents/documentation/software_documentation/sav/sequencinganalysisviewer_userguide_15020619c.pdf} \cr For other implementations (and inspiration) please see \cr \url{http://search.cpan.org/dist/Bio-IlluminaSAV/Bio/IlluminaSAV.pm} \cr \url{https://bitbucket.org/invitae/illuminate}
+}
+\keyword{package}
+
diff --git a/man/savR.Rd b/man/savR.Rd
new file mode 100644
index 0000000..08434bc
--- /dev/null
+++ b/man/savR.Rd
@@ -0,0 +1,30 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/savR-methods.R
+\docType{methods}
+\name{savR}
+\alias{savR}
+\alias{savR,character-method}
+\alias{savR,missing-method}
+\title{Build a SAV project}
+\usage{
+savR(object)
+
+\S4method{savR}{character}(object)
+
+\S4method{savR}{missing}()
+}
+\arguments{
+\item{object}{String Path to Flowcell data}
+}
+\description{
+Constructor to build a \link{savProject-class} object and populate it. A SAV
+project consists of binary files generated by an Illumina sequencing run
+and placed in a folder named "InterOp". This folder contains a number
+of ".bin" files that contain statistics about the run.  Creating
+this object parses all of the files and makes the data available for analysis.
+}
+\examples{
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+fc
+}
+
diff --git a/man/savTileFormat-class.Rd b/man/savTileFormat-class.Rd
new file mode 100644
index 0000000..4b985e4
--- /dev/null
+++ b/man/savTileFormat-class.Rd
@@ -0,0 +1,29 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllClasses.R
+\docType{class}
+\name{savTileFormat-class}
+\alias{savTileFormat-class}
+\title{Tile Metrics formatter}
+\description{
+Lane, tile, code, value.  Codes are:
+}
+\details{
+\tabular{ll}{
+100 \tab Cluster Density \cr
+101 \tab PF Cluster Density \cr
+102 \tab Number of clusters \cr
+103 \tab Number of PF clusters \cr
+400 \tab Control lane \cr
+}
+}
+\section{Slots}{
+
+\describe{
+\item{\code{name}:}{vector of column names}
+\item{\code{type}:}{vector of data types of elements}
+\item{\code{lengths}:}{vector of byte lengths for each element}
+\item{\code{order}:}{vector of column names for sorting}
+\item{\code{version}:}{integer version number (header consists of version (1b), length (1b))}
+}
+}
+
diff --git a/man/tileMetrics.Rd b/man/tileMetrics.Rd
new file mode 100644
index 0000000..cbeb5e2
--- /dev/null
+++ b/man/tileMetrics.Rd
@@ -0,0 +1,50 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/AllGenerics.R, R/SavR-accessors.R
+\docType{methods}
+\name{tileMetrics}
+\alias{tileMetrics}
+\alias{tileMetrics,savProject-method}
+\title{Get Tile Metrics}
+\usage{
+tileMetrics(project)
+
+\S4method{tileMetrics}{savProject}(project)
+}
+\arguments{
+\item{project}{SAV project}
+}
+\value{
+sorted data.frame of tile metrics
+}
+\description{
+Returns the Tile Metrics SAV data.
+}
+\details{
+Metrics for each tile are encoded in the following format:
+\tabular{ll}{
+cluster density: \tab 100 \cr
+PF cluster density: \tab 101 \cr
+number of clusters: \tab 102 \cr
+number of PF clusters: \tab 103 \cr
+phasing for read N: \tab (200 + (N - 1) * 2) \cr
+prephasing for read N: \tab (201 + (N - 1) * 2) \cr
+percent aligned for read N: \tab (300 + N - 1) \cr
+control lane: \tab 400 \cr
+}
+
+\describe{
+ \item{\code{lane}:}{Lane number}
+ \item{\code{tile}:}{Tile ID}
+ \item{\code{code}:}{Code described above}
+ \item{\code{value}:}{Value for code key}
+}
+}
+\examples{
+example(savR)
+colnames(tileMetrics(fc))
+}
+\references{
+Codes for Tile Metrics were obtained from the Python Illuminate package: \cr
+\url{https://bitbucket.org/invitae/illuminate}
+}
+
diff --git a/tests/testthat.R b/tests/testthat.R
new file mode 100644
index 0000000..f791bca
--- /dev/null
+++ b/tests/testthat.R
@@ -0,0 +1,4 @@
+library(testthat)
+library(savR)
+
+test_check("savR")
diff --git a/tests/testthat/test_accessors.R b/tests/testthat/test_accessors.R
new file mode 100644
index 0000000..81dc760
--- /dev/null
+++ b/tests/testthat/test_accessors.R
@@ -0,0 +1,34 @@
+require(savR)
+context("Data Accessor Test")
+
+# use skip_on_cran() for long running tests
+
+# test for avaliablitily of example data in extdata folder
+miseq_available <- function() {
+  if (!file.exists(system.file("extdata", "MiSeq", package="savR"))) {
+    skip("Example data not available")
+  }
+}
+
+# data folder not included in built package, skip if missing
+data_available <- function() {
+  if (!file.exists("../data")) {
+    skip("Test data folder not available")
+  }
+}
+
+test_that("data accessors", {
+  miseq_available()
+  fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+  expect_equal(dim(correctedIntensities(fc)), c(3116, 18), label = "correctedIntensities")
+  expect_equal(dim(qualityMetrics(fc)), c(3116, 53), label = "qualityMetrics")
+  expect_equal(dim(tileMetrics(fc)), c(648, 4), label = "tileMetrics")
+  expect_equal(dim(extractionMetrics(fc)), c(3116, 11), label = "extractionMetrics")
+})
+
+test_that("errorMetrics", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/AAF39")
+  expect_equal(dim(errorMetrics(fc)), c(700, 9), label = "errorMetrics")
+})
\ No newline at end of file
diff --git a/tests/testthat/test_load.R b/tests/testthat/test_load.R
new file mode 100644
index 0000000..2ed9fa5
--- /dev/null
+++ b/tests/testthat/test_load.R
@@ -0,0 +1,69 @@
+require(savR)
+context("Load InterOp File Test")
+
+# use skip_on_cran() for long running tests
+
+# test for avaliablitily of example data in extdata folder
+miseq_available <- function() {
+  if (!file.exists(system.file("extdata", "MiSeq", package="savR"))) {
+    skip("Example data not available")
+  }
+}
+
+# data folder not included in built package, skip if missing
+data_available <- function() {
+  if (!file.exists("../data")) {
+    skip("Test data folder not available")
+  }
+}
+
+test_that("Load sample MiSeq data and check values", {
+  miseq_available()
+  fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+  expect_equivalent(run(fc)["Id"], "131030_M01243_0072_000000000-A58WM", label = "FCID check")
+  expect_equal(cycles(fc), 82, label = "cycle count")
+  expect_equal(directions(fc), 1, label = "directions")
+  expect_equal(clusters(fc,1L),35470731, label="clusters")
+})
+
+test_that("Load sample HiSeq RapidRun (QMetricsOut.bin v5) data and check values", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/BHF5GNADXX")
+  expect_equivalent(run(fc)["Id"], "150115_SN7001401_0253_BHF5GNADXX", label = "FCID check")
+  expect_equal(cycles(fc), 209, label = "cycle count")
+  expect_equal(directions(fc), 2, label = "directions")
+  expect_equal(clusters(fc,1L), 184790371, label="clusters")
+})
+
+test_that("Load empty qmetrics file", {
+  data_available()
+  expect_warning(fc <- savR("../data/EMPTY"), regexp="Unable to determine", label="Empty binary file")
+})
+
+test_that("Load sample MiSeq with ErrorMetricsOut.bin", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/AAF39")
+  expect_equal(dim(errorMetrics(fc)), c(700, 9))
+})
+
+test_that("Load ErrorMetrics with unreported lanes", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/AC5J04ACXX")
+})
+
+test_that("Load NextSeq500 flowcell", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/NextSeq")
+  expect_equivalent(run(fc)["Id"], "150602_NEXTSEQ1_0018_H2LGHAFXX", label = "FCID check")
+})
+
+test_that("Load v5 qmetrics", {
+  skip_on_cran()
+  data_available()
+  fc <- savR("../data/BC5CAHACXX")
+  expect_true("savQualityFormatV5" %in% names(fc at parsedData), "loading savQualityFormatV5")
+})
diff --git a/vignettes/savR.Rnw b/vignettes/savR.Rnw
new file mode 100644
index 0000000..45faad9
--- /dev/null
+++ b/vignettes/savR.Rnw
@@ -0,0 +1,196 @@
+\documentclass[letterpaper,11pt,oneside,final,onecolumn,article]{memoir}
+\usepackage{microtype}
+\usepackage{helvet}
+\usepackage{pxfonts}
+\usepackage{eulervm}
+\usepackage{nicefrac}
+\usepackage{graphicx}
+\usepackage{textcomp}
+\usepackage[numbers,square,comma,sort&compress]{natbib}
+\usepackage{soul, color, ulem} % underline, overstrike, highlight 
+\usepackage{amssymb}
+\usepackage{hyperref} % URL's
+\usepackage{memhfixc} % should have loaded already, memoir bugs
+
+\setlrmarginsandblock{.75in}{.75in}{1}
+\setulmarginsandblock{.75in}{.75in}{1}
+\checkandfixthelayout
+
+\pagestyle{empty}
+
+\renewcommand{\abstractname}{} % no ``abstract''
+\renewcommand{\bibname}{} % no ``bibliography''
+
+\setsecheadstyle{\Large\sffamily\raggedright}
+\setsubsecheadstyle{\large\sffamily\raggedright}
+\setsubsubsecheadstyle{\normalsize\sffamily\raggedright}
+
+%\VignetteIndexEntry{Using savR}
+
+\begin{document}
+
+\fvset{listparameters={\setlength{\topsep}{0pt}}} 
+\renewenvironment{Schunk}{\vspace{\topsep}}{\vspace{\topsep}} 
+\renewenvironment{Schunk}{\vspace{5pt}}{\vspace{5pt}} 
+
+\title{Using savR}
+\author{R. Brent Calder}
+
+\maketitle
+
+<<prepare>>=
+library(savR)
+@
+
+<<intro,cache=T>>=
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+@
+
+<<show>>=
+fc
+@
+
+<<doPfPlot,eval=F>>=
+pfBoxplot(fc)
+@
+<<pfPlot,echo=F>>=
+png(filename="pf.png", width=400, height=300, res=72)
+pfBoxplot(fc)
+invisible(dev.off())
+@
+
+\begin{figure}[htb]
+\begin{center}
+\includegraphics[width=3in]{pf.png}
+\end{center}
+\caption{Boxplot of total vs. PF clusters}
+\label{fig:fp}
+\end{figure}
+
+\section*{Introduction}
+
+The Illumina Sequence Analysis Viewer (SAV) is a Windows application provided by Illumina that 
+presents graphs made in real time from data collected over the course of basecalling.  This data was 
+previously also made available in HTML format for inspection after the run; however, it is now
+preserved in binary format and not simply parsed by users who wish to perform automated quality
+assessment.  Here is presented \textit{savR}, an R package to parse the binary output, generate 
+QC assessment plots and make the data available to users of Illumina sequencing instruments.
+For more information about Illumina SAV, please consult the Illumina iCom website and the
+Sequencing Analysis Viewer User's Guide, available
+\href{https://duckduckgo.com/?q=sequencing%20analysis%20viewer%20user%27s%20guide}{\textit{online}}.
+
+\section*{Description}
+
+The \texttt{savR} function is passed a path to an Illumina HiSeq or MiSeq run, and returns a
+\texttt{savProject} object, containing the parsed data.  Accessor methods are available for
+information in the \texttt{RunInfo.xml} file as well as the parsed SAV Metrics files.  These include
+corrected intensities, quality metrics, tile metrics, and extraction metrics.  The \textit{savR}
+package comes with an example MiSeq data set which can be loaded thusly:
+
+<<intro2,eval=F>>=
+fc <- savR(system.file("extdata", "MiSeq", package="savR"))
+@
+
+\subsection*{RunInfo.xml}
+
+The \texttt{RunInfo.xml} file is parsed and stored in the slots of the \texttt{savProject} object.
+There are accessor methods for the project's \texttt{location}, \texttt{reads}, number of ``ends'' 
+or \texttt{directions}, the \texttt{run} ID, the number of \texttt{cycles}, and a description of
+the \texttt{flowcellLayout}.
+
+<<ri>>=
+directions(fc)
+reads(fc)
+cycles(fc)
+flowcellLayout(fc)
+@
+
+\subsection*{Corrected intensitites}
+
+Corrected intensity metrics (obtained from \texttt{CorrectedIntMetricsOut.bin}) can be inspected
+by the \texttt{correctedIntestites} accessor method:
+
+<<ciex>>=
+head(correctedIntensities(fc), n=1)
+@
+
+This is a \texttt{data.frame} of intensity metrics; one line for each set of lane, tile and cycle 
+measurements. Reported statistics include average intensity, corrected intensity (for cross-talk between 
+bases and phasing/pre-phasing), called corrected intensities, number of called bases and signal to
+noise ratio.  There are methods which act upon \texttt{savProject} objects to produce QC plots, for example 
+plotIntensity to assess signal intensity for each channel as in figure \ref{fig:ci}.
+
+<<doCiPlot,eval=F>>=
+plotIntensity(fc)
+@
+
+<<ciPlot,echo=F>>=
+png(filename="ci.png", width=250, height=400, res=72)
+plotIntensity(fc)
+invisible(dev.off())
+@
+
+\begin{figure}[htb]
+\begin{center}
+\includegraphics[width=2.25in]{ci.png}
+\end{center}
+\caption{Corrected intensity plot: cycle 1, base ``A''.}
+\label{fig:ci}
+\end{figure}
+
+\subsection*{Quality Metrics}
+
+The quality metrics (\texttt{QMetricsOut.bin}) file contains per-lane/tile/cycle metrics for the number
+of clusters with quality at each PHRED value from 1-50.
+
+
+<<qmex>>=
+head(qualityMetrics(fc), n=1)
+@
+
+<<doQhPlot,eval=F>>=
+qualityHeatmap(fc,1,1)
+@
+
+<<qhPlot,echo=F>>=
+png(filename="qh.png", width=400, height=300, res=72)
+qualityHeatmap(fc,1,1)
+invisible(dev.off())
+@
+
+\begin{figure}[h]
+\begin{center}
+\includegraphics[width=3.5in]{qh.png}
+\end{center}
+\caption{Quality heatmap: lane 1, read 1.}
+\label{fig:qh}
+\end{figure}
+
+\subsection*{Tile Metrics}
+
+The tile metrics (\texttt{TileMetricsOut.bin}) file contains coded information about per-lane/cycle/tile cluster density,
+pass-filter clusters, phasing and pre-phasing data.  Consult the \texttt{tileMetrics} help page for more information.
+
+<<tmex>>=
+head(tileMetrics(fc), n=4)
+@
+
+\subsection*{Extraction Metrics}
+
+The extraction metrics (\texttt{ExtractionMetricsOut.bin}) file contains per-lane/cycle/tile information about per-base FWHM
+(full width pixel size of clusters at half maximum) and 90th \%-ile intensity of signal intensity.
+
+<<example2>>=
+head(extractionMetrics(fc), n=1)
+@
+
+\section*{Coda}
+
+There is a convenience function (\texttt{buildReports}), which partially reconstructs the Illumina reports folder
+that was previously generated by the Illumina instrument software and which was superseded by SAV and InterOp files.
+
+
+
+
+
+\end{document}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-bioc-savr.git



More information about the debian-med-commit mailing list