Repository 'crosscontamination_barcode_filter'
hg clone https://toolshed.g2.bx.psu.edu/repos/iuc/crosscontamination_barcode_filter

Changeset 1:253c9448f524 (2019-06-03)
Previous changeset 0:582b7bd4ae4c (2019-01-24) Next changeset 2:5ade5cf200da (2019-06-12)
Commit message:
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/crosscontamination_barcode_filter commit f967afe562781e5c8ed4e24e9d1e0bc3ebb29401
modified:
crosscontamination_barcode_filter.xml
scripts/batch_plotting_functions.R
scripts/config_assertions.R
scripts/contamination_plot.R
scripts/crosscontamination_filter.R
scripts/reorder_matrix_headers.R
added:
scripts/generateTestData.R
test-data/out.pdf
test-data/out.table
test-data/test.matrix
removed:
test-data/out3.subtable
test-data/test.pdf
test-data/test.table
b
diff -r 582b7bd4ae4c -r 253c9448f524 crosscontamination_barcode_filter.xml
--- a/crosscontamination_barcode_filter.xml Thu Jan 24 09:52:58 2019 -0500
+++ b/crosscontamination_barcode_filter.xml Mon Jun 03 14:55:24 2019 -0400
[
@@ -1,15 +1,7 @@
 <tool id="crosscontamination_barcode_filter" name="Cross-contamination Barcode Filter" version="@VERSION@">
     <description>for use in plate-based barcoded analyses</description>
     <macros>
-        <token name="@VERSION@">0.1</token>
-        <macro name="assert_conts" >
-            <assert_contents>
-                <has_text text="/CreationDate" />
-                <has_text text="/Producer" />
-                <has_line line="startxref" />
-                <has_line line="%%EOF" />
-            </assert_contents>
-        </macro>
+        <token name="@VERSION@">0.2</token>
         <macro name="sanitize_batch">
             <sanitizer invalid_char="">
                 <valid initial="string.digits">
@@ -35,10 +27,11 @@
                     <add value="&#41;"/> <!-- right parenthesis -->
                 </valid>
             </sanitizer>
-        </macro>        
+        </macro>
     </macros>
     <requirements>
-        <requirement type="package" version="2.2.1" >r-ggplot2</requirement>
+        <requirement type="package" version="3.1.1">r-ggplot2</requirement>
+        <requirement type="package" version="1.12.2">r-data.table </requirement>
     </requirements>
     <version_command><![CDATA[
         Rscript '$__tool_directory__/scripts/crosscontamination_filter.R' | head -1 | cut -d' ' -f 2
@@ -61,12 +54,12 @@
 spec = list(
     barcodes = '$input_barcodes',
     format = list(
-        "1-96"   = c(1,3,5,7),
-        "97-192" = c(2,4,6,8)
+        "1-96"   = c(1,3),
+        "97-192" = c(2,4)
     ),
     plates = list(
-        "1" = c(1,2,3,4),
-        "2" = c(5,6,7,8)
+        "1" = c(1,2),
+        "2" = c(3,4)
     )
 )
 #elif str($inbuilt_spec.select_use) == "custom":
@@ -74,7 +67,7 @@
     barcodes = '$input_barcodes',
     format = list(
     #for $i, $s in enumerate($inbuilt_spec.barcode_format)
-        "${s.range_start}-${s.range_end}" = c( ${s.batches} ) 
+        "${s.range_start}-${s.range_end}" = c( ${s.batches} )
         #if $i < len(list($inbuilt_spec.barcode_format)) - 1
         ,
         #end if
@@ -123,7 +116,7 @@
             </when>
         </conditional>
         <section name="advanced" expanded="false" title="RegEx Parameters" >
-            <param name="regex_extract" type="text" value=".*P(\\d)_(\\d)_([ACTG]+)" label="RegEx to extract Plate, Batch, and Barcodes from headers" >
+            <param name="regex_extract" type="text" value=".*P(\\d)_B(\\d)_([ACTG]+)" label="RegEx to extract Plate, Batch, and Barcodes from headers" >
                 <expand macro="sanitize_regex" />
             </param>
             <param name="regex_display" type="text" value="P\\1_B\\2_\\3" label="RegEx to replace Plate, Batch, and Barcodes from headers" >
@@ -137,44 +130,40 @@
     </outputs>
     <tests>
         <test><!-- Inbuilt MPI -->
-            <param name="input_table" value="out3.subtable" />
+            <param name="input_table" value="test.matrix" />
             <param name="input_barcodes" value="celseq_barcodes.192.raw" />
             <conditional name="inbuilt_spec" >
                 <param name="select_use" value="mpi_sagar" />
             </conditional>
-            <output name="out_plots" >
-                <expand macro="assert_conts" />
-            </output>
-            <output name="out_table" value="test.table" />
+            <output name="out_plots" value="out.pdf" compare="sim_size" />
+            <output name="out_table" value="out.table" />
         </test>
         <test><!-- Plate and Lane test -->
-            <param name="input_table" value="out3.subtable" />
+            <param name="input_table" value="test.matrix" />
             <param name="input_barcodes" value="celseq_barcodes.192.raw" />
             <conditional name="inbuilt_spec" >
                 <param name="select_use" value="custom" />
                 <repeat name="barcode_format" >
                     <param name="range_start" value="1"/>
                     <param name="range_end" value="96" />
-                    <param name="batches" value="1,3,5,7" />
+                    <param name="batches" value="1,3" />
                 </repeat>
                 <repeat name="barcode_format" >
                     <param name="range_start" value="97"/>
                     <param name="range_end" value="192" />
-                    <param name="batches" value="2,4,6,8" />
+                    <param name="batches" value="2,4" />
                 </repeat>
                 <repeat name="plate_format" >
                     <param name="plate" value="1" />
-                    <param name="batches" value="1,2,3,4" />
+                    <param name="batches" value="1,2" />
                 </repeat>
                 <repeat name="plate_format" >
                     <param name="plate" value="2" />
-                    <param name="batches" value="5,6,7,8" />
+                    <param name="batches" value="3,4" />
                 </repeat>
             </conditional>
-            <output name="out_plots" >
-                <expand macro="assert_conts" />
-            </output>
-            <output name="out_table" value="test.table" />
+            <output name="out_plots" value="out.pdf" compare="sim_size" />
+            <output name="out_table" value="out.table" />
         </test>
     </tests>
     <help><![CDATA[
@@ -194,10 +183,10 @@
 
 Consider the following experimental setup, with a list of 100 possible barcodes, used over 3 sequencing plates, with each plate containing 4 unique batches, and each plate using a specific subset of the 100 barcodes.
 
-:: 
+::
 
  Barcodes
-    
+
   1 - 10 | AAA AAC AAT AAG ACA AGA ATA CAC GAG TAT
  11 - 20 | CCC CCA CCT CCG CTC CGC TCT GCG TCT CGT
     .
@@ -209,7 +198,7 @@
  Plate 1  +-------+-------+-------+-------+
           |  B1   |  B2   |  B3   |  B4   |
           +-------+-------+-------+-------+
-             1-50   51-100  51-100   1-50  
+             1-50   51-100  51-100   1-50
 
  Plate 2  +-------+-------+-------+-------+
           |  B5   |  B6   |  B7   |  B8   |
@@ -219,7 +208,7 @@
  Plate 3  +-------+-------+-------+-------+
           |  B9   |  B10  |  B11  |  B12  |
           +-------+-------+-------+-------+
-             1-40   41-80    1-40   41-80 
+             1-40   41-80    1-40   41-80
 
 
 ****
@@ -244,4 +233,3 @@
         <citation type="doi">10.1007/978-1-4939-7768-0_15</citation>
     </citations>
 </tool>
-
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/batch_plotting_functions.R
--- a/scripts/batch_plotting_functions.R Thu Jan 24 09:52:58 2019 -0500
+++ b/scripts/batch_plotting_functions.R Mon Jun 03 14:55:24 2019 -0400
[
@@ -1,95 +1,119 @@
 #!/usr/bin/env R
 
+suppressPackageStartupMessages(require(data.table))
+
 ##
 ## Batch Plotting Functions
 ##
-calculatePlateIndexes <- function(plate.form, full.barcode.size, num.plates){
-    #' Determine plotting positions of plate lines (under false model)
-    #'
-    #' Assumes all plates are the same size and span the full range of the
-    #' barcodes.
-    #'
-    #' @param plate.form list of vectors mapping plates to batches
-    #' @param full.barcode.size size of the complete barcodes list
-    #' @param num.plates, number of plates
-    #' @return sequence of discrete plate-boundary positions
-    batches.per.plate <- length(plate.form[[1]])
-    plate.size <- batches.per.plate * full.barcode.size
-
-    return(seq(0, num.plates * plate.size, plate.size))
-}
-
-
-calculateFullBarcodeIndexes <- function(num.batches, full.barcode.size){
-    #' Determines plotting position of batch lines (under false model)
-    #'
-    #' For N batches and a list of actually detected barcodes in the header,
-    #' generates where the blue lines should be
-    #'
-    #' @param num.batches number of batches in experiment
-    #' @param full.barcode.size size of all barcodes
-    #' @return sequence of discrete batch positions
-    bsize <- full.barcode.size
-    return(seq(0, num.batches * bsize, bsize))
-}
-
-
-
-calculateRealBarcodeIndexes <- function(barcode.form, full.barcode.size){
-    #' Determine plotting position of the true batch lines (under true model)
-    #'
-    #' For N batches a list of actually USED barcodes as given by the spec,
-    #' generates where the green lines should be
+calculateBarcodePositions <- function(barcode.form, full.barcode.size){
+    #' Determine x-axis positions of all batches under the context of
+    #' unfiltered barcodes (full set), filtered (real set), dividing line
+    #' (the position of real set in the full set).
     #'
     #' @param barcode.form list of barcode formats and the batches they map to
     #' @param full.barcode.size size of all barcodes
-    #' @return list of useful vectors: true batch positions using whole matrix,
-    #'         true batch positions using the filtered matrix which contains
-    #'         only real barcodes, and a list of batches and their respective
-    #'         sizes.
-    batches <- c()
+    #' @return dataframe of batch information: sizes, unfiltered, filtered,
+    #'         and dividing line.
+    sizes <- list(B0=0)
+
     res <- sapply(names(barcode.form), function(key){
         rng <- as.integer(unlist(strsplit(key, '-')))
         size.of.range <- length(seq(rng[1],rng[2]))
         sub.batches <- barcode.form[[key]]  # 1,3,5,7 or 2,4,6,8
         res2 <- lapply(sub.batches, function(bat){
-            batches[[bat]] <<- size.of.range
+            sizes[[paste("B",bat, sep="")]] <<- size.of.range
         })
     })
+
     ## We now have sizes per batch, in order of batch
     ## Need to place these at positions after each full barcode size
-    positions <- c()
-    real_positions <- c(0)
+
+    ## Below we have "positions" which has the END positions of each batch under
+    ## the assumption of using full barcodes. The "real_positions" contains the
+    ## END positions of each batch under the assumption of using only the real
+    ## subsetted barcodes.
+    unfilter_positions <- list(B0=0)
+    filtered_positions <- list(B0=0)
+    filter_in_unfilter <- list(B0=0) ## dividing line between real and false barcodes in each batch
+
+    res <- sapply(sort(names(sizes)), function(batch.name){
 
-    res <- sapply(1:length(batches), function(b){
-        batch.start <- (b-1) * full.barcode.size
-        batch.size <- batches[[b]]
-        positions <<- c(positions, batch.start + batch.size)
-        real_positions[[b+1]] <<- batch.size + real_positions[[b]]
+        batch.num <- as.integer(sub("B","", batch.name))
+        if (batch.num > 0){
+            batch.size <- sizes[[batch.name]]  ## 96
+            batch.name.previous = paste("B", batch.num-1, sep="")
+            batch.start <- unfilter_positions[[batch.name.previous]]
+            filt.batch.start <- filtered_positions[[batch.name.previous]]
+
+            unfilter_positions[[batch.name]] <<- batch.start + full.barcode.size
+            filtered_positions[[batch.name]] <<- filt.batch.start + batch.size
+            filter_in_unfilter[[batch.name]] <<- batch.start + batch.size
+        }
     })
 
-    real_positions <- real_positions[2:length(real_positions)]   
-    
-    return(list(unfiltered=positions,filtered=real_positions, batches=batches))
+    # Put into a dataframe, merging lists on their common names
+    dd <- data.frame(rbindlist(list(
+        unfilter_positions=unfilter_positions,
+        filter_in_unfilter=filter_in_unfilter,
+        filtered_positions=filtered_positions,
+        sizes=sizes),  ## sizes go last to not mess up the column name ordering
+        use.names = TRUE, idcol = TRUE))
+
+    rownames(dd) <- dd$.id
+    dd <- dd[,!(colnames(dd) %in% ".id")]
+
+    return(dd)
 }
 
-calculateRealPlateIndexes <- function(plate.form, batches, num.plates){
-    #' Determine true plate positions given variable batch sizes
+calculatePlatePositions <- function(plate.form, full.barcode.size, all.batch.data){
+    #' Determine the x-axis plate positions for each of the unfiltered and filtered sets
     #'
     #' Given the true size of each batch, and which batches exist in which plates
     #' calculate the size of each plate
     #'
     #' @param plate.form list of vectors mapping plates to batches
-    #' @param batches list of batches and their respective sizes
-    #' @param num.plates number of plates
-    #' @return sequence of plate positions
-    batches.per.plate <- length(plate.form[[1]])
+    #' @param full.barcode.size size of the full set of barcodes
+    #' @param all.batch.data the output of 'calculateBarcodePositions'
+    #' @return dataframe of plate information pertaining to positions and sizes of plates
+    unfilter.plates = list(P0=0)
+    filtered.plates = list(P0=0)
+    unfilter.plates.sizes = list(P0=0)
+    filtered.plates.sizes = list(P0=0)
+
+    res <- sapply(sort(names(plate.form)), function(plate.num){
+
+        unfilter.plate.size = 0
+        filtered.plate.size = 0
+
+        batches <- plate.form[[plate.num]]
 
-    size.of.plate <- 0
-    res <- sapply(plate.form[[1]], function(batch){
-        batch.size <- batches[[batch]]
-        size.of.plate <<- size.of.plate + batch.size
+        res2 <- sapply(sort(batches), function(batch.num){
+            batch.size <- all.batch.data["sizes",paste("B", batch.num, sep="")]
+
+            unfilter.plate.size <<- unfilter.plate.size + full.barcode.size
+            filtered.plate.size <<- filtered.plate.size + batch.size
+        })
+
+        plate.name = paste("P", plate.num, sep="")
+        plate.name.previous = paste("P", as.integer(plate.num) - 1, sep="")
+
+        unfilter.plates.sizes[[plate.name]] <<- unfilter.plate.size
+        filtered.plates.sizes[[plate.name]] <<- filtered.plate.size
+
+        filtered.plates[[plate.name]] <<- filtered.plates[[plate.name.previous]] + filtered.plate.size
+        unfilter.plates[[plate.name]] <<- unfilter.plates[[plate.name.previous]] + unfilter.plate.size
     })
 
-    return(seq(0, num.plates * size.of.plate, size.of.plate))
+    # Put into a dataframe, merging lists on their common names
+    dd <- data.frame(rbindlist(list(
+        unfilter.plates=unfilter.plates,
+        unfilter.plates.sizes=unfilter.plates.sizes,
+        filtered.plates=filtered.plates,
+        filtered.plates.sizes=filtered.plates.sizes),
+        use.names = TRUE, idcol = TRUE))
+
+    rownames(dd) <- dd$.id
+    dd <- dd[,!(colnames(dd) %in% ".id")]
+
+    return(dd)
 }
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/config_assertions.R
--- a/scripts/config_assertions.R Thu Jan 24 09:52:58 2019 -0500
+++ b/scripts/config_assertions.R Mon Jun 03 14:55:24 2019 -0400
[
@@ -31,12 +31,13 @@
     return(barcodes[!not.in])
 }
 
+
 checkNoMissingBarcodes <- function(headers, barcodes){
     #' Extracts barcodes in the headers and compares them with those in barcodes
     #'
     #' @param headers matrix headers, must be of P1_B2_ACTG format
     #' @param barcodes full list of barcodes
-    barcs.in.matrix <- unique(sort(sub(".*_.*_([ACTG]+)", "\\1", headers)))
+    barcs.in.matrix <- unique(sort(sub("^.*_([ACTGN]+)$", "\\1", headers)))
     not.in <- !(barcs.in.matrix %in% barcodes)
     if (sum(not.in) > 0){
         message("Warning: Barcodes in matrix not in barcodes file\n", barcs.in.matrix[not.in])
@@ -45,9 +46,26 @@
     }
 }
 
+checkBatchNamesAreValid <- function(headers){
+    #' Checks that Plate and Batch names follow good conventions
+    #' i.e. Batch names are NOT reused across plates
+    #'
+    #' @param headers matrix headers in P1_B2_ACTG format
+    plate.and.batch <- unique(sort(sub("^(.*)_([ATCGN]+)$", "\\1", headers)))
+    message("Discovered ", length(plate.and.batch), " batches: ", paste(plate.and.batch, collapse=" "))
+
+    batch.only <- sub("^.*_(B\\d)$", "\\1", plate.and.batch)
+    dupes.batches <- batch.only[duplicated(batch.only)]
+
+    if (length(dupes.batches) > 0){
+        stop("Batches ", paste(dupes.batches, collapse=" "), " have duplicate names in other plates!")
+    }
+}
+
+
 assertNoMissingBatches <- function(format, plates){
     #' Checks the barcode and plate spec match
-    #' 
+    #'
     #' These must specify the same batches.
     #'
     #' @param format barcode format, ranges to batches
@@ -56,14 +74,17 @@
     batches.form = c()
     batches.plate = c()
     for (form in format){batches.form = c(batches.form, form)}
-    for (plate in plates){batches.plate = c(batches.plate, plate)}
+    for (plate in plates){
+        batches.plate = c(batches.plate, plate)
+    }
 
     if (length(batches.plate) != length(batches.form)){
         stop("Error: The number of batches specified in the plate do not match those given in the barcode format")
     }
 
-    range.form <- seq(min(batches.form), max(batches.form))
-    range.plate <- seq(min(batches.plate), max(batches.plate))
+    #range.form <- seq(min(batches.form), max(batches.form))
+    range.form <- unique(sort(batches.form))
+    range.plate <- unique(sort(batches.plate))
 
     if (sum(!(range.form %in% batches.form)) > 0){
         stop("Error: Missing batch in barcode format")
@@ -83,9 +104,11 @@
     barcodes <- scan(spec$barcodes, what="", sep="\n")
     num.barcodes <- length(barcodes)
     num.plates <- length(names(spec$plate))
+
     used.barcodes <- checkNoMissingRanges(spec$format, barcodes)
     num.batches <- assertNoMissingBatches(spec$format, spec$plates)
     checkNoMissingBarcodes(matrix.headers, used.barcodes)
+    checkBatchNamesAreValid(matrix.headers)
 
     return(list(barc=barcodes, barc.n=num.barcodes, plates.n=num.plates, batch.n=num.batches))
-}
+}
\ No newline at end of file
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/contamination_plot.R
--- a/scripts/contamination_plot.R Thu Jan 24 09:52:58 2019 -0500
+++ b/scripts/contamination_plot.R Mon Jun 03 14:55:24 2019 -0400
[
b'@@ -1,8 +1,8 @@\n #!/usr/bin/env R\n \n-require(ggplot2)\n+suppressPackageStartupMessages(require(ggplot2))\n \n-log10histoPlot <- function(columncounts, title=""){\n+log10histoPlot <- function(title="", columncounts){\n     #\' Log10 histogram plot\n     #\'\n     #\' @param columncounts colSums(input_matrix)\n@@ -17,124 +17,152 @@\n     return(p1)\n }\n \n-contaminationPlot <- function(columncounts, title = "",\n-                              indexes.plates, indexes.fullbc, indexes.truebc,\n-                              filtered=FALSE)\n-{\n-    #\' Plots true and false barcodes\n-    #\'\n-    #\'\n-    #\' @param columncounts colSums(input_matrix)\n-    #\' @param title plot title\n-    #\' @param indexes.plates plate line positions\n-    #\' @param indexes.fullbc full batch line positions\n-    #\' @param indexes.truebc true batch line positions\n-    #\' @param filtered specifies whether the positions have been adjusted for true barcodes\n-    #\' @return ggplot grob\n-    dfer <- data.frame(colcounts=columncounts)\n+## This is calculated by the first call to contaminationPlot\n+## and then re-used by the second call.\n+ylim.max = NULL\n \n-    ## Remove indexes where plates and full barcodes mix\n-    indexes.fullbc = indexes.fullbc[!(indexes.fullbc %in% indexes.plates)]\n-    \n-    nit <- length(indexes.truebc)\n-    nif <- length(indexes.fullbc)\n-    nip <- length(indexes.plates)\n-    mval <- max(dfer)\n-  \n-    ## Aesthetics\n-    min.height <- -200\n-    tf.spacing.left <- 12\n-    tf.spacing.right <- 12   \n-    tf.height <- mval - 10000\n-    bn.height <- mval - 2000\n-    plate.color <- "grey"\n-    plate.text.color <- "black"\n-    plate.text.alpha <- 0.5\n-    plate.text.size <- 3\n-    plate.height <- 2* mval / 5\n-    plate.spacing <- if (filtered) 12 else 24\n-    plate.height.text <- plate.height - 3000\n-    \n-    truebcs <- data.frame(\n-        x=indexes.truebc, y=rep(min.height,nit),\n-        xend=indexes.truebc, yend=rep(mval,nit)\n-    )\n-    fullbcs <- data.frame(\n-        x=indexes.fullbc, y=rep(min.height,nif),\n-        xend=indexes.fullbc, yend=rep(mval,nif)\n-    )\n-    platess <- data.frame(\n-        x=indexes.plates, y=rep(min.height,nip),\n-        xend=indexes.plates, yend=rep(plate.height,nip)\n-    )\n-    connecting.bar <- data.frame(\n-        xsta = min(indexes.plates), ysta = min.height,\n-        xfin = max(indexes.plates), yfin = min.height\n-    )\n-      \n-    p1 <- ggplot()\n-\n-    if (!filtered){\n-        p1 <- p1 +\n-            geom_segment(data=truebcs, aes(x=x,y=y,xend=xend,yend=yend - 4000), col=\'grey\', lty=2, size=0.2) + \n-            geom_segment(data=fullbcs, aes(x=x,y=y,xend=xend,yend=yend), col=\'blue\', lty=1, size=0.4, alpha=0.2)\n+contaminationPlot <- function(title, columndata, barcode.data, plate.data, RAW)\n+{\n+    coldata = data.frame(colsums=columndata)\n+    maxval = max(coldata)\n+    # Set once and once only\n+    if (is.null(ylim.max)){\n+        ylim.max <<- maxval + 500\n     }\n-    else {\n-        p1 <- p1 +\n-            geom_segment(data=truebcs, aes(x=x,y=y,xend=xend,yend=yend), col=\'blue\', lty=1, size=0.4, alpha=0.2)\n-    }\n-    \n-    p1 <- p1 +\n-        geom_segment(data=platess, aes(x=x,y=y,xend=xend,yend=yend), col=plate.color, lty=1, size=1) +\n-        geom_segment(data=connecting.bar, aes(x=xsta,y=ysta,xend=xfin,yend=yfin), col=plate.color, lty=1, size=1) +\n-        geom_point(\n-            data=dfer, aes(x=1:length(rownames(dfer)), y=dfer$colcounts),\n-            pch = 16, cex = 1) +\n-        theme(plot.title = element_text(hjust = 0.5),\n-              axis.ticks.x=element_blank(), axis.ticks.y=element_blank(),\n-              axis.text.x=element_blank()) +\n-        labs(title=paste("Contamination Plot\\n", title), y="Library Size", x="Barcode Index") +\n-        scale_y_continuous(breaks=seq(0,mval + 10000, 10000)) +\n-        scale_x_continuous(breaks=NULL)\n \n-    ## Add true/false and batch labels\n-    res <- lapply(indexes.truebc, function(xval){\n-        batch <- match(xval, indexes.truebc)\n+    drawPlates <- function(plate.dat'..b't.tf.height <- maxval * 2/5\n+        batch.text.tf.spacing <- 12\n+        batch.text.alpha <- 0.8\n+        batch.text.size <- 3\n+        batch.label.text.size <- 6\n+        batch.height <- maxval * 4/5\n+        divide.height <- maxval * 4/5\n+        batch.spacing <- 24\n+\n+        boundary.pos <- barcode.data["filtered_positions",]\n+        plate.pos <- unname(unlist(plate.data["filtered.plates",])) ## just want values\n+\n+        if (RAW){\n+            boundary.pos <- barcode.data["unfilter_positions",]\n+            divider.pos <- barcode.data["filter_in_unfilter",]\n+            plate.pos <- unname(unlist(plate.data["unfilter.plates",])) ## just want values\n+        }\n+\n+\n+        zzz <- lapply(names(boundary.pos), function(batch.name){\n+            batch.num = as.integer(sub("B","",batch.name))\n+            batch.xval = unname(unlist(boundary.pos[[batch.name]]))\n+\n+            # Plot boundary line only if not intersecting with a plate line\n+            if (!(batch.xval %in% plate.pos)){\n+                gplot <<- gplot + geom_segment(aes(x=batch.xval, xend=batch.xval, y=batch.minyval, yend=batch.height),\n+                                               color=boundary.color, lty=boundary.style, size=boundary.size)\n+            }\n+\n+            ## Plot labels (except P0)\n+            if (batch.name != "B0"){\n+                if (RAW){\n+                    divide.xval = unname(unlist(divider.pos[[batch.name]]))\n+\n+                    ## Plot the divider line\n+                    gplot <<- gplot + geom_segment(aes(x=divide.xval, xend=divide.xval, y=batch.minyval, yend=divide.height),\n+                                               color=divide.color, lty=divide.style, size=divide.size)\n+\n+                    ## Plot the True/False labels\n+                    gplot <<- gplot + annotate("text", x=divide.xval - batch.text.tf.spacing, label="True positives",\n+                                               size=batch.text.size, y=batch.text.tf.height, angle=+90,\n+                                               color=divide.text.true.color, alpha=batch.text.alpha)\n+                    gplot <<- gplot + annotate("text", x=divide.xval + batch.text.tf.spacing, label="False positives",\n+                                               size=batch.text.size, y=batch.text.tf.height, angle=-90,\n+                                               color=divide.text.false.color, alpha=batch.text.alpha)\n+                    ## Plot the Batch names\n+                    gplot <<- gplot + annotate("text", x=divide.xval, label=batch.name,\n+                                               size=batch.label.text.size, y=batch.text.height, angle=0,\n+                                               color = divide.text.name.color, alpha=batch.text.alpha)\n+                } else {\n+                    ## Plot the Batch names between blue lines\n+                    gplot <<- gplot + annotate("text", x=batch.xval, label=batch.name,\n+                                               size=batch.label.text.size, y=batch.text.height, angle=0,\n+                                               color = divide.text.name.color, alpha=batch.text.alpha)\n+                }\n+            }\n+        })\n+    }\n+\n+\n+    plotCells <- function(coldata){\n+        gplot <<- gplot + geom_point(data=coldata, aes(x=1:nrow(coldata), y=coldata$colsums), pch = 16, cex = 1)\n+    }\n+\n+    plotTheme <- function(){\n+        gplot <<- gplot + theme(plot.title = element_text(hjust = 0.5),\n+                                axis.ticks.x=element_blank(), axis.ticks.y=element_blank(),\n+                                axis.text.x=element_blank()) +\n+            labs(title=paste("Contamination Plot\\n", title), y="Library Size", x="Barcode Index") +\n+            coord_cartesian(ylim = c(-200, ylim.max)) +\n+            scale_x_continuous(breaks=NULL)\n+    }\n+\n+\n+    gplot <- ggplot()\n+    drawPlates(plate.data)\n+    drawBatches(barcode.data, plate.data)\n+    plotCells(coldata)\n+    plotTheme()\n+\n+    return(gplot)\n+}\n'
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/crosscontamination_filter.R
--- a/scripts/crosscontamination_filter.R Thu Jan 24 09:52:58 2019 -0500
+++ b/scripts/crosscontamination_filter.R Mon Jun 03 14:55:24 2019 -0400
[
@@ -1,5 +1,5 @@
 #!/usr/bin/env R
-VERSION = "0.1"
+VERSION = "0.2"
 
 args = commandArgs(trailingOnly = T)
 
@@ -9,6 +9,8 @@
 }
 
 source(args[1])
+
+## debug in debug dir
 source(file.path(script.dir, "config_assertions.R"))
 source(file.path(script.dir, "batch_plotting_functions.R"))
 source(file.path(script.dir, "reorder_matrix_headers.R"))
@@ -28,46 +30,30 @@
 num.batches <- sc$batch.n
 num.plates <- sc$plates.n
 
-real.indexes = calculateRealBarcodeIndexes(spec$format, num.barcodes)
-plate.indexes = calculatePlateIndexes(spec$plates, num.barcodes, num.plates)
-plate.indexes.real = calculateRealPlateIndexes(spec$plates, real.indexes$batches, num.plates)
-
-ordering <- reorderMatrixHeaders(barcodes, colnames(input_matrix), spec$format)
 
-## Unfiltered
-nmatrix <- input_matrix[,ordering$all]
+barcode.data <- calculateBarcodePositions(spec$format, num.barcodes)
+plate.data <- calculatePlatePositions(spec$plates, num.barcodes, barcode.data)
 
-plot.prefilter <- contaminationPlot(
-    colSums(nmatrix),
-    title="Pre-Filter",
-    plate.indexes,
-    calculateFullBarcodeIndexes(num.batches, num.barcodes),
-    real.indexes$unfiltered
-)
+ordering <- reorderMatrixHeaders(barcodes, colnames(input_matrix), spec$format, spec$plates)
 
-
-## Filtered
-cmatrix <- input_matrix[,ordering$correct]
+## Unfiltered, but sorted matrix
+nmatrix <- input_matrix[,ordering$all]
+plot.prefilter <- contaminationPlot("Pre-Filter", colSums(nmatrix),
+                                    barcode.data, plate.data, RAW=TRUE)
 
-plot.postfilter <- contaminationPlot(
-    colSums(cmatrix),
-    title="Post-Filter",
-    plate.indexes.real,
-    calculateFullBarcodeIndexes(num.batches, num.barcodes),
-    real.indexes$filtered,
-    filtered = T
-)
+## Filtered, but sorted matrix
+cmatrix <- input_matrix[,ordering$filtered]
+plot.postfilter <- contaminationPlot("Post-Filter", colSums(cmatrix),
+                                     barcode.data, plate.data, RAW=FALSE)
 
-plot.histogram <- log10histoPlot(
-    colSums(cmatrix),
-    "Histogram of Post-Filter Matrix Counts"
-)
+plot.histogram.pre <- log10histoPlot("Histogram of Pre-Filter Matrix Counts", colSums(nmatrix))
+plot.histogram.post <- log10histoPlot("Histogram of Post-Filter Matrix Counts", colSums(cmatrix))
 
 pdf(out.pdf)
 plot.prefilter
 plot.postfilter
-plot.histogram
+plot.histogram.pre
+plot.histogram.post
 dev.off()
 
-
 write.table(cmatrix, file=out.table, quote=FALSE, na="0", sep="\t")
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/generateTestData.R
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/generateTestData.R Mon Jun 03 14:55:24 2019 -0400
[
@@ -0,0 +1,67 @@
+num.genes = 500
+num.cells.per.batch.good = 96
+num.cells.per.batch.bad = 11
+num.cells.per.batch.empty = 85
+
+barcodes = read.table('../test-data/celseq_barcodes.192.raw', stringsAsFactors=F)[,1]
+
+barcodes.1_96 <- barcodes[1:96]
+barcodes.97_192 <- barcodes[97:192]
+
+
+goodCell <- function(){
+    return(rnbinom(n=num.genes, size=0.1, mu=6))
+}
+
+badCell <- function(){
+    return(rnbinom(n=num.genes, size=0.1, mu=0.5))
+}
+
+emptyCell <- function(){
+    return(rnbinom(n=num.genes, size=0.1, mu=0.1))
+}
+
+generateGoodBatch <- function(batch.prefix="P1_B1", bar.codes){
+    tmp.cell <- goodCell()
+    for (c in 2:num.cells.per.batch.good){
+        tmp.cell <- cbind(tmp.cell, goodCell())
+    }
+    bar.good <- paste(batch.prefix, bar.codes, sep="_")
+    colnames(tmp.cell) <- bar.good
+    return(tmp.cell)
+}
+
+
+generateBadBatch <- function(batch.prefix="P1_B1", bar.codes){
+    tmp.cell <- emptyCell()
+    for (c in 2:num.cells.per.batch.empty){
+        tmp.cell <- cbind(tmp.cell, emptyCell())
+    }
+    for (c in 1:num.cells.per.batch.bad){
+        tmp.cell <- cbind(tmp.cell, badCell())
+    }
+    bar.bad <- paste(batch.prefix, bar.codes, sep="_")
+    colnames(tmp.cell) <- bar.bad
+    return(tmp.cell)
+}
+
+makeBatch <- function(batch.prefix, odd=TRUE){
+    batch.good <- generateGoodBatch(batch.prefix, bar.codes=if(odd) barcodes.1_96 else barcodes.97_192)
+    batch.bad <- generateBadBatch(batch.prefix, bar.codes=if(odd) barcodes.97_192 else barcodes.1_96)
+    batch <- cbind(batch.good, batch.bad)
+
+    ## Shuffle columns
+    batch.shuff <- batch[,sample(ncol(batch))]
+    return(batch.shuff)
+}
+
+batch.1 <- makeBatch("P1_B1", odd=TRUE)
+batch.2 <- makeBatch("P1_B2", odd=FALSE)
+batch.3 <- makeBatch("P2_B3", odd=TRUE)
+batch.4 <- makeBatch("P2_B4", odd=FALSE)
+
+total.matrix <- cbind(batch.1, batch.2, batch.3, batch.4)
+rownames(total.matrix) <- paste("GENE", 1:nrow(total.matrix), sep="")
+
+write.table(as.matrix(total.matrix), file="test.matrix",
+            col.names=NA, sep='\t', quote=FALSE)
\ No newline at end of file
b
diff -r 582b7bd4ae4c -r 253c9448f524 scripts/reorder_matrix_headers.R
--- a/scripts/reorder_matrix_headers.R Thu Jan 24 09:52:58 2019 -0500
+++ b/scripts/reorder_matrix_headers.R Mon Jun 03 14:55:24 2019 -0400
[
@@ -12,7 +12,7 @@
     return(sub(regex.from, regex.to, col.names))
 }
 
-reorderMatrixHeaders <- function(barcodes, headers, barcode.format){
+reorderMatrixHeaders <- function(barcodes, fixed.headers, barcode.format, plate.format){
     #' Reorder headers to segment wanted and unwanted barcodes on opposite sides
     #' of each batch
     #'
@@ -20,42 +20,61 @@
     #' @param headers input matrix headers
     #' @param barcode.format batch list specifying valid barcodes for each batch
     #' @return list of all barcodes sorted bilaterally by batch, and true barcodes
-    form <- barcode.format
+
     batch.ordering <- list()
-    batch.ordering.correct <- list()
+    batch.ordering.filtered <- list()
 
-    res <- sapply(names(form), function(key){
+    res <- sapply(names(barcode.format), function(key){
         rng <- as.integer(unlist(strsplit(key, '-')))
         ranges <- seq(rng[1],rng[2])
 
+        # Barcodes wanted and unwanted for this range of batches
         barc.wanted <- barcodes[ranges]
         barc.unwant <- barcodes[!(barcodes %in% barc.wanted)]
 
-        sub.batches <- form[[key]]  # 1,3,5,7 or 2,4,6,8
+        sub.batches <- barcode.format[[key]]  # 1,3,5,7 or 2,4,6,8
+
         res2 <- lapply(sub.batches, function(bat){
-            batch_bar <- headers[grepl(paste("P\\d_B",bat,"_([ACGT]+)", sep=""), headers)]
-            barcs.in.batch <- sub("P._B._([ACGT]+)", "\\1", batch_bar)
-            b.wanted <- batch_bar[barcs.in.batch %in% barc.wanted]
-            b.unwant <- batch_bar[barcs.in.batch %in% barc.unwant]
+            batch.match <- paste("_B",bat,"_",sep="")
+            headers.in.batch <- fixed.headers[grepl(batch.match, fixed.headers)]
+            barcodes.in.batch <- sub(".*_([ATCGN]+)$", "\\1", headers.in.batch)
+
+            headers.in.batch.wanted <- headers.in.batch[barcodes.in.batch %in% barc.wanted]
+            headers.in.batch.unwant <- headers.in.batch[barcodes.in.batch %in% barc.unwant]
+
+            if (sum(headers.in.batch.wanted %in% headers.in.batch.unwant) > 0){
+                stop("Barcode given twice!", headers.in.batch.wanted[headers.in.batch.wanted %in% headers.in.batch.unwant])
+            }
+
+            headers.in.batch.neworder <- c(headers.in.batch.wanted, headers.in.batch.unwant)
+            batch.name <- paste("B", bat, sep="")
 
-            if (sum(b.wanted %in% b.unwant) > 0){
-                stop("Barcode given twice!", b.wanted[b.wanted %in% b.unwant])
-            }
-            barc_order <- c(b.wanted, b.unwant)
-            batch.ordering[[bat]] <<- barc_order
-            batch.ordering.correct[[bat]] <<- b.wanted
+            batch.ordering[[batch.name]] <<- headers.in.batch.neworder
+            batch.ordering.filtered[[batch.name]] <<- headers.in.batch.wanted
+        })
+    })
+    ## Now we have sorted all our barcodes in each batch to the correct order
+    ## we just have to sort the batches into the correct order according to plating setup
+    barcode.ordering <- c()
+    barcode.ordering.filtered <- c()
+
+    res <- sapply(sort(names(plate.format)), function(plate.num){
+        batches <- plate.format[[plate.num]]
+
+        ## Preserve batch order on plates
+        res2 <- sapply(batches, function(batch.num){
+            batch.name <- paste("B", batch.num, sep="")
+            barcs <- batch.ordering[[batch.name]]
+            barcs.filtered <- batch.ordering.filtered[[batch.name]]
+
+            barcode.ordering <<- c(barcode.ordering, barcs)
+            barcode.ordering.filtered <<- c(barcode.ordering.filtered, barcs.filtered)
         })
     })
 
-    barcode.ordering <- c()
-    barcode.ordering.correct <- c()
-
-    res <- lapply(1:length(batch.ordering), function(bat){
-        barc_order <- batch.ordering[[bat]]
-        barc_order.correct <- batch.ordering.correct[[bat]]
-        barcode.ordering <<- c(barcode.ordering, barc_order)
-        barcode.ordering.correct <<- c(barcode.ordering.correct, barc_order.correct)
-    })
-
-    return(list(all=barcode.ordering,correct=barcode.ordering.correct))
-}
+    return(list(
+        all=barcode.ordering,
+        filtered=barcode.ordering.filtered,
+        debug.barcodes = batch.ordering
+    ))
+}
\ No newline at end of file
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/out.pdf
b
Binary file test-data/out.pdf has changed
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/out.table
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/out.table Mon Jun 03 14:55:24 2019 -0400
b
b'@@ -0,0 +1,501 @@\n+P1_B1_CCACAA\tP1_B1_AGGACA\tP1_B1_ACTCTG\tP1_B1_TGTCTG\tP1_B1_AGGATC\tP1_B1_AGGAAG\tP1_B1_GTTGAG\tP1_B1_CTCAGA\tP1_B1_ACGTGA\tP1_B1_GAAGGA\tP1_B1_GTGAAG\tP1_B1_TGGTTG\tP1_B1_TGAACC\tP1_B1_AACGAG\tP1_B1_AGCTAG\tP1_B1_TCACAG\tP1_B1_ACCAAC\tP1_B1_ATGTCG\tP1_B1_GTCTCA\tP1_B1_CTAGGA\tP1_B1_GGTAAC\tP1_B1_TAGGAC\tP1_B1_TAACGG\tP1_B1_TTCCAG\tP1_B1_GATACG\tP1_B1_CACCAA\tP1_B1_CGATGA\tP1_B1_TAGTGG\tP1_B1_GAAGAC\tP1_B1_GTGACA\tP1_B1_CTGTTG\tP1_B1_CACTTC\tP1_B1_CGTCTA\tP1_B1_TGAAGG\tP1_B1_GCAACA\tP1_B1_GTGATC\tP1_B1_AGCTCA\tP1_B1_GATCTG\tP1_B1_GAATGG\tP1_B1_TGTACG\tP1_B1_ACAAGC\tP1_B1_ACTTCG\tP1_B1_CGATTG\tP1_B1_ATCACG\tP1_B1_GAGTGA\tP1_B1_ACCAGA\tP1_B1_TGCAAC\tP1_B1_TTCTCG\tP1_B1_ACCATG\tP1_B1_TCATCC\tP1_B1_ACAGTG\tP1_B1_GTGGAA\tP1_B1_GACGAA\tP1_B1_AGTGCA\tP1_B1_AGCTTC\tP1_B1_GGACAA\tP1_B1_TGGTGA\tP1_B1_ACTCAC\tP1_B1_ACAGGA\tP1_B1_AGACTC\tP1_B1_AACCTC\tP1_B1_CCATAG\tP1_B1_AAGCCA\tP1_B1_GAATCC\tP1_B1_TTGTGC\tP1_B1_CAGAAG\tP1_B1_CTATCC\tP1_B1_TGCAGA\tP1_B1_GTACTC\tP1_B1_ATTGCG\tP1_B1_AGTGTC\tP1_B1_GAGTTG\tP1_B1_TGTCGA\tP1_B1_TCTTGC\tP1_B1_CATGCA\tP1_B1_ACGTAC\tP1_B1_CTAGTG\tP1_B1_GTACCA\tP1_B1_AGACAG\tP1_B1_CTAGAC\tP1_B1_CTTCGA\tP1_B1_ACAGAC\tP1_B1_CATGTC\tP1_B1_TTCACC\tP1_B1_GATCGA\tP1_B1_TGAGGA\tP1_B1_CTAAGC\tP1_B1_ACGTTG\tP1_B1_AGACCA\tP1_B1_TCCGAA\tP1_B1_ACTCGA\tP1_B1_CTCATG\tP1_B1_GTACAG\tP1_B1_GACAGA\tP1_B1_CACTCA\tP1_B1_GACAAC\tP1_B2_CCGTAA\tP1_B2_AGTAGG\tP1_B2_TATCGC\tP1_B2_ATTCGC\tP1_B2_GTATCG\tP1_B2_CCTATG\tP1_B2_CCAATC\tP1_B2_AAGCAC\tP1_B2_CGTTAC\tP1_B2_TAGCTC\tP1_B2_GCATTC\tP1_B2_GCAGAA\tP1_B2_AGTACC\tP1_B2_TTGCTG\tP1_B2_TTGCAC\tP1_B2_GGTTAG\tP1_B2_GCTTAC\tP1_B2_GCCATA\tP1_B2_TCAACG\tP1_B2_ATGCTC\tP1_B2_TTGGCA\tP1_B2_AACACC\tP1_B2_CGCATA\tP1_B2_TTGGAG\tP1_B2_AAGGTG\tP1_B2_GTTAGG\tP1_B2_GTATGC\tP1_B2_GTAACC\tP1_B2_ATGACC\tP1_B2_CCTGAA\tP1_B2_GGTATG\tP1_B2_ATGGAC\tP1_B2_CGGTTA\tP1_B2_CAGGAA\tP1_B2_ATCCAC\tP1_B2_GGCTTA\tP1_B2_GCAATG\tP1_B2_GAGCAA\tP1_B2_ACATGG\tP1_B2_AGCGAA\tP1_B2_TTGGTC\tP1_B2_GGATCA\tP1_B2_GAGGTA\tP1_B2_ATCGCA\tP1_B2_TACCAC\tP1_B2_TACCGA\tP1_B2_AGAACG\tP1_B2_ATCGTG\tP1_B2_ATCCGA\tP1_B2_CCGATA\tP1_B2_TGTTCC\tP1_B2_TACGCA\tP1_B2_CGCTAA\tP1_B2_CTAACG\tP1_B2_GATTGC\tP1_B2_GCTTCA\tP1_B2_CCTTGA\tP1_B2_TGTAGC\tP1_B2_GGAATC\tP1_B2_AAGTGC\tP1_B2_GGATAC\tP1_B2_CACGTA\tP1_B2_GCATGA\tP1_B2_TACTCC\tP1_B2_GCTAAG\tP1_B2_ATCAGC\tP1_B2_ATACGG\tP1_B2_GGTAGA\tP1_B2_CCTACA\tP1_B2_TCTAGG\tP1_B2_CGAACA\tP1_B2_ATGAGG\tP1_B2_TTCGAC\tP1_B2_AGATGC\tP1_B2_GCGTTA\tP1_B2_AGGCTA\tP1_B2_GCTCTA\tP1_B2_TGTTGG\tP1_B2_CTCGAA\tP1_B2_CTGCTA\tP1_B2_CGTAAG\tP1_B2_ATGCAG\tP1_B2_CCAGTA\tP1_B2_GGTGTA\tP1_B2_TGATCG\tP1_B2_ATCTCC\tP1_B2_AACTGG\tP1_B2_TTACGC\tP1_B2_TTGCGA\tP1_B2_CAATGC\tP1_B2_ACGGTA\tP1_B2_CGTTCA\tP1_B2_TACAGG\tP1_B2_CATTGG\tP1_B2_TATCCG\tP1_B2_CCATCA\tP2_B3_AGCTAG\tP2_B3_CGATTG\tP2_B3_CTAGTG\tP2_B3_AACGAG\tP2_B3_AGACCA\tP2_B3_ATTGCG\tP2_B3_TGAACC\tP2_B3_ACTCGA\tP2_B3_CATGCA\tP2_B3_AGGATC\tP2_B3_CTATCC\tP2_B3_GTCTCA\tP2_B3_GAGTTG\tP2_B3_TGCAAC\tP2_B3_TGCAGA\tP2_B3_CAGAAG\tP2_B3_CTCAGA\tP2_B3_GATCGA\tP2_B3_ACGTAC\tP2_B3_GAATCC\tP2_B3_GAAGAC\tP2_B3_GTGAAG\tP2_B3_ACAGAC\tP2_B3_CTAAGC\tP2_B3_TGAGGA\tP2_B3_ACGTTG\tP2_B3_GAGTGA\tP2_B3_ACCAGA\tP2_B3_CCACAA\tP2_B3_ACGTGA\tP2_B3_CGATGA\tP2_B3_CGTCTA\tP2_B3_TGTACG\tP2_B3_TGTCGA\tP2_B3_ACAGGA\tP2_B3_CACCAA\tP2_B3_GTTGAG\tP2_B3_AGACAG\tP2_B3_AGGACA\tP2_B3_CACTTC\tP2_B3_TCATCC\tP2_B3_TTCCAG\tP2_B3_GGTAAC\tP2_B3_CTGTTG\tP2_B3_TAACGG\tP2_B3_AGACTC\tP2_B3_TCACAG\tP2_B3_GACAGA\tP2_B3_GGACAA\tP2_B3_TGGTTG\tP2_B3_ACCATG\tP2_B3_TGGTGA\tP2_B3_AGCTCA\tP2_B3_ACTCTG\tP2_B3_GTGACA\tP2_B3_GTGGAA\tP2_B3_GCAACA\tP2_B3_TTGTGC\tP2_B3_CCATAG\tP2_B3_GAATGG\tP2_B3_GTACCA\tP2_B3_CTAGAC\tP2_B3_AGCTTC\tP2_B3_TGAAGG\tP2_B3_AGTGTC\tP2_B3_TTCACC\tP2_B3_GATACG\tP2_B3_GTACTC\tP2_B3_ACTTCG\tP2_B3_ATGTCG\tP2_B3_ACAAGC\tP2_B3_GATCTG\tP2_B3_TAGTGG\tP2_B3_CTCATG\tP2_B3_CACTCA\tP2_B3_ACTCAC\tP2_B3_TTCTCG\tP2_B3_GAAGGA\tP2_B3_AGTGCA\tP2_B3_CTAGGA\tP2_B3_GACGAA\tP2_B3_CATGTC\tP2_B3_TAGGAC\tP2_B3_TCCGAA\tP2_B3_TCTTGC\tP2_B3_AACCTC\tP2_B3_ACCAAC\tP2_B3_AGGAAG\tP2_B3_ATCACG\tP2_B3_GACAAC\tP2_B3_GTACAG\tP2_B3_ACAGTG\tP2_B3_TGTCTG\tP2_B3_AAGCCA\tP2_B3_CTTCGA\tP2_B3_GTGATC\tP2_B4_TGTAGC\tP2_B4_ATGCAG\tP2_B4_GCATGA\tP2_B4_AACTGG\tP2_B4_ATCTCC\tP2_B4_GCTTCA\tP2_B4_GATTGC\tP2_B4_ATGCTC\tP2_B4_GGATCA\tP2_B4_GCAGAA\tP2_B4_GTAACC\tP2_B4_TAGCTC\tP2_B4_GGTGTA\tP2_B4_GTATCG\tP2_B4_AAGCAC\tP2_B4_ATCGTG\tP2_B4_GTTAGG\tP2_B4_TCAACG\tP2'..b'\t0\t0\t3\t0\t6\t0\t0\t4\t0\t0\t1\t0\t0\t8\t0\t39\t0\t5\t0\t11\t35\t0\t0\t1\t10\t0\t0\t0\t0\t0\t0\t0\t6\t7\t0\t41\t0\t5\t0\t0\t2\t6\t0\t0\t0\t8\t1\t0\t1\t0\t0\t4\t0\t0\t2\t0\t0\t0\t3\t0\t0\t1\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t23\t1\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t16\t3\t0\t8\t0\t5\t0\t0\t0\t2\t1\t0\t0\t0\t0\t0\t0\t52\t1\t0\t0\t0\t110\t1\t63\t0\t64\t0\t0\t0\t5\t0\t0\t1\t0\t0\t0\t68\t132\t0\t0\t0\t0\t25\t0\t0\t10\t0\t7\t0\t0\t16\t0\t0\t0\t2\t0\t15\t0\t11\t3\t2\t0\t0\t3\t0\t12\t1\t0\t26\t0\t0\t0\t0\t0\t7\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t2\t0\t2\t0\t0\t0\t3\t0\t5\t0\t0\t0\t0\t0\t0\t0\t2\t15\t0\t2\t117\t0\t0\t3\t0\t0\t5\t0\t0\t0\t0\t0\t20\t0\t23\t0\t0\t0\t0\t0\t0\t4\t0\t10\t0\t0\t14\t2\t0\t2\t0\t2\t0\t0\t41\t17\t0\t0\t0\t0\t0\t0\t17\t0\t0\t8\t1\t7\t0\t2\t0\t0\t9\t0\t0\t0\t17\t56\t0\t0\t65\t0\t0\t0\t1\t0\t0\t0\t0\t0\t12\t0\t0\t21\t30\t1\t3\t4\t0\t7\t0\t4\t0\t0\t56\t0\t13\t0\t1\t23\t0\t21\t2\t0\t0\t6\t0\t0\t12\t0\t0\t33\t0\t4\t0\t0\t7\t0\t0\t0\n+GENE497\t0\t69\t0\t1\t0\t1\t0\t6\t1\t0\t1\t47\t0\t0\t44\t0\t0\t3\t7\t0\t0\t17\t0\t1\t23\t0\t16\t0\t0\t0\t0\t0\t0\t8\t0\t3\t0\t0\t0\t13\t1\t0\t1\t0\t20\t4\t0\t0\t0\t3\t1\t20\t0\t1\t0\t2\t140\t21\t0\t0\t0\t1\t71\t0\t0\t0\t34\t0\t2\t0\t0\t1\t0\t3\t0\t0\t0\t0\t0\t0\t0\t2\t0\t6\t15\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t1\t8\t0\t0\t9\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t1\t0\t133\t0\t19\t3\t144\t6\t0\t0\t11\t2\t18\t0\t26\t1\t0\t1\t6\t0\t8\t0\t0\t9\t0\t0\t0\t0\t19\t0\t15\t91\t0\t0\t0\t0\t0\t38\t0\t1\t0\t7\t0\t0\t0\t21\t0\t16\t0\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t145\t0\t0\t1\t0\t0\t0\t0\t0\t190\t0\t0\t4\t0\t0\t0\t2\t0\t0\t0\t0\t0\t3\t6\t0\t28\t0\t0\t17\t1\t0\t26\t25\t0\t0\t0\t2\t3\t0\t0\t0\t4\t0\t51\t13\t1\t0\t8\t76\t0\t0\t1\t0\t0\t10\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t37\t10\t2\t0\t5\t0\t2\t0\t0\t0\t154\t2\t0\t0\t0\t3\t1\t2\t2\t0\t1\t0\t18\t0\t1\t0\t0\t0\t0\t3\t0\t0\t8\t0\t0\t0\t29\t0\t0\t11\t0\t0\t5\t0\t0\t0\t0\t36\t0\t1\t0\t0\t0\t8\t0\t0\t0\t0\t0\t77\t0\t31\t10\t1\t14\t9\t0\t0\t19\t1\t0\t0\t18\t17\t1\t0\t0\t0\t0\t0\t0\t1\t0\t221\t0\t35\t0\t1\t0\t0\t2\t0\t5\t0\t0\t4\t3\t25\t2\t5\t0\t4\t0\t0\t8\t0\t4\t11\t1\t9\t0\t0\t0\t3\t3\t11\t0\t0\t0\t0\t0\t0\t11\t0\t0\t0\t23\t11\t15\t0\t0\t1\t0\t2\t15\t0\t0\t0\t16\t4\t4\t3\t0\t3\t9\t0\t0\t0\n+GENE498\t0\t0\t58\t0\t11\t0\t0\t0\t0\t0\t0\t5\t1\t0\t0\t0\t0\t0\t106\t0\t0\t0\t0\t0\t0\t0\t2\t0\t20\t0\t6\t0\t0\t0\t0\t0\t0\t13\t7\t0\t2\t0\t0\t0\t29\t26\t1\t41\t42\t2\t0\t0\t44\t2\t0\t0\t10\t20\t0\t0\t1\t0\t0\t0\t89\t0\t0\t112\t18\t0\t0\t0\t2\t0\t0\t0\t72\t26\t2\t0\t4\t12\t7\t0\t0\t6\t0\t0\t0\t15\t0\t0\t0\t12\t8\t0\t1\t0\t90\t1\t0\t1\t38\t0\t6\t0\t0\t0\t0\t0\t0\t29\t0\t0\t44\t31\t0\t0\t5\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t0\t0\t3\t0\t13\t0\t0\t0\t0\t0\t2\t107\t0\t42\t0\t0\t0\t0\t0\t0\t11\t3\t0\t1\t0\t36\t0\t2\t0\t37\t0\t44\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t10\t0\t0\t0\t0\t0\t10\t0\t0\t0\t0\t0\t0\t0\t15\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t0\t10\t166\t0\t0\t1\t63\t95\t0\t0\t0\t40\t0\t0\t0\t0\t0\t0\t0\t0\t0\t10\t17\t0\t55\t0\t0\t0\t0\t72\t0\t0\t0\t1\t0\t0\t0\t0\t2\t0\t3\t0\t0\t2\t0\t0\t9\t1\t0\t3\t23\t1\t0\t0\t0\t51\t0\t0\t9\t0\t0\t0\t171\t1\t0\t0\t41\t0\t0\t0\t8\t18\t54\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t2\t0\t0\t0\t0\t0\t0\t18\t17\t8\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t3\t0\t7\t0\t146\t27\t10\t17\t0\t14\t30\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t10\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t64\t0\t0\t9\t0\t0\t49\t0\t0\t1\t0\t0\t0\t0\t0\t15\t0\t0\t0\t0\t0\t0\t29\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n+GENE499\t1\t0\t0\t2\t29\t0\t6\t0\t0\t1\t22\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t36\t35\t0\t0\t0\t0\t19\t20\t9\t0\t0\t0\t0\t0\t0\t23\t0\t0\t2\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t1\t11\t0\t27\t0\t49\t0\t0\t2\t4\t0\t0\t0\t0\t0\t18\t0\t0\t1\t0\t0\t22\t0\t3\t20\t0\t0\t0\t1\t26\t0\t0\t1\t0\t0\t0\t6\t0\t0\t0\t0\t25\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t1\t89\t0\t0\t0\t1\t0\t0\t87\t0\t0\t3\t0\t8\t14\t0\t0\t1\t0\t2\t0\t1\t1\t0\t73\t0\t0\t4\t0\t1\t0\t7\t0\t0\t0\t1\t0\t0\t0\t0\t0\t1\t1\t0\t0\t0\t0\t9\t9\t0\t1\t0\t75\t1\t0\t6\t0\t0\t2\t1\t0\t4\t0\t1\t0\t0\t0\t0\t9\t12\t107\t0\t0\t32\t0\t17\t0\t27\t0\t1\t0\t2\t0\t0\t0\t0\t1\t12\t1\t0\t0\t0\t31\t2\t8\t0\t1\t1\t0\t9\t7\t9\t0\t0\t22\t10\t2\t19\t0\t32\t0\t0\t1\t0\t0\t0\t11\t0\t0\t2\t25\t35\t0\t0\t0\t0\t0\t0\t20\t0\t4\t0\t0\t0\t129\t0\t0\t0\t0\t0\t19\t0\t12\t0\t0\t0\t0\t0\t5\t0\t0\t67\t17\t9\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t1\t3\t0\t0\t23\t2\t0\t101\t1\t1\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t42\t0\t0\t0\t1\t0\t4\t0\t0\t0\t0\t4\t3\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t1\t1\t0\t0\t0\t0\t48\t0\t3\t1\t5\t2\t56\t0\t0\t0\t6\t0\t1\t0\t39\t0\t42\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t1\n+GENE500\t3\t0\t0\t0\t0\t0\t33\t0\t0\t0\t0\t146\t1\t0\t2\t0\t0\t28\t0\t16\t9\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t11\t1\t142\t2\t0\t2\t0\t17\t3\t54\t0\t8\t0\t0\t0\t0\t0\t3\t56\t0\t0\t0\t2\t0\t14\t8\t0\t0\t0\t0\t0\t0\t0\t6\t0\t3\t0\t4\t0\t0\t0\t0\t0\t11\t0\t0\t0\t0\t0\t39\t0\t0\t0\t11\t0\t2\t5\t0\t28\t0\t0\t0\t54\t0\t0\t0\t0\t0\t0\t0\t0\t42\t0\t0\t0\t0\t0\t0\t0\t12\t0\t0\t0\t0\t18\t0\t5\t56\t0\t0\t76\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t23\t22\t4\t8\t0\t1\t0\t6\t0\t0\t0\t0\t1\t2\t0\t0\t0\t14\t0\t0\t1\t12\t2\t0\t11\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t8\t16\t0\t0\t1\t10\t0\t0\t0\t0\t0\t22\t7\t0\t1\t3\t0\t0\t1\t6\t0\t5\t0\t1\t0\t0\t1\t0\t1\t24\t0\t0\t2\t0\t6\t0\t36\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t1\t0\t7\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t12\t0\t0\t1\t0\t75\t0\t9\t0\t0\t26\t28\t0\t0\t0\t1\t0\t0\t0\t0\t37\t0\t15\t0\t0\t0\t0\t6\t0\t0\t22\t0\t36\t0\t0\t0\t0\t31\t0\t37\t0\t1\t1\t1\t1\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t70\t0\t5\t46\t0\t0\t0\t7\t0\t4\t0\t0\t0\t4\t0\t15\t0\t0\t0\t2\t9\t0\t0\t0\t8\t0\t0\t0\t0\t1\t2\t1\t67\t0\t0\t2\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t2\t0\t0\t2\t0\t0\t0\t0\t0\t0\t140\t31\t0\t0\t0\t0\t2\t25\t3\t0\t0\t0\t20\t11\t5\t0\t114\t2\t0\t0\t17\t0\t0\t8\t0\t0\t0\t0\t50\t0\t0\t0\t10\t0\t0\n'
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/out3.subtable
--- a/test-data/out3.subtable Thu Jan 24 09:52:58 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
b
b'@@ -1,176 +0,0 @@\n-WD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AACACC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AACCTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AACGAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AACTGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AAGCAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AAGCCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AAGGTG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AAGTGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACAAGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACAGAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACAGGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACAGTG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACATGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACCAAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACCAGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACCATG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACGGTA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACGTAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACGTGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACGTTG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACTCAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACTCGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACTCTG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ACTTCG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGAACG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGACAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGACCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGACTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGATGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGCGAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGCTAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGCTCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGCTTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGGAAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGGACA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGGATC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGGCTA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGTACC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGTAGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGTGCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_AGTGTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATACGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCACG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCAGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCCAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCCGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCGCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCGTG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATCTCC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGACC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGAGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGCAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGCTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGGAC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATGTCG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATTCGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_ATTGCG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CAATGC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CACCAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CACGTA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CACTCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CACTTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CAGAAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CAGGAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CATGCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CATGTC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CATTGG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCAATC\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCACAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCAGTA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCATAG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCATCA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCGATA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCGTAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCTACA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCTATG\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCTGAA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CCTTGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CGAACA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CGATGA\tWD_DP_120218_P1_1.fastq_WD_DP_120218_P1_1_CGATTG\tWD_DP_12021'..b'\t0\t0\t0\t7\t0\t0\t0\t0\t0\t1\t1\t0\t5\t1\t0\t0\t0\t3\t0\t1\t0\t2\t7\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t2\t1\t0\t0\t5\t0\t0\t0\t0\t0\t1\t8\t6\t0\t0\t0\t0\t3\t2\t0\t0\t0\t8\t0\t0\t0\t1\t0\t0\t0\t1\t0\t1\t2\t0\t0\t0\t10\t0\t0\t0\t0\t0\t3\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t1\t9\t0\t0\t0\t0\t1\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t1\t0\t2\t0\t1\t8\t1\t5\t0\t0\t0\t4\t2\t0\t4\t4\t5\t0\t2\t0\t0\t0\t0\t0\t1\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t0\t0\t1\t0\t1\t0\t0\t1\t0\t0\t0\t1\t6\t0\t0\t0\t2\t4\t4\t0\t0\t0\t1\t0\t0\t0\t0\t2\t0\t5\t0\t0\t1\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t3\t1\t0\t2\t0\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t1\t0\t0\t3\t1\t0\t0\t2\t1\t4\t0\t2\t2\t0\t0\t1\t0\t0\t1\t0\t0\t0\t5\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t4\t3\t0\t1\t0\t2\t2\t0\t0\t0\t4\t1\t0\t0\t1\t1\t1\t7\t0\t0\t0\t0\t0\t0\t0\t0\t8\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t1\t0\t1\t0\t2\t1\t0\t0\t0\t1\t6\t0\t1\t3\t0\t0\t0\t0\t0\t0\t1\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t3\t0\t7\t0\t3\t0\t0\t0\t0\t2\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t1\t0\t0\t0\n-ENSDARG00000104782\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t2\t3\t2\t0\t1\t0\t4\t4\t0\t1\t0\t0\t12\t0\t5\t0\t0\t1\t1\t2\t0\t1\t2\t0\t0\t0\t2\t2\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t2\t0\t6\t0\t0\t0\t5\t0\t6\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t3\t1\t0\t0\t0\t0\t1\t0\t0\t0\t1\t1\t2\t0\t0\t1\t0\t0\t0\t1\t1\t0\t1\t7\t0\t0\t1\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t4\t1\t0\t0\t5\t0\t0\t0\t0\t0\t0\t4\t13\t0\t0\t0\t0\t8\t0\t1\t0\t1\t0\t0\t0\t0\t1\t0\t0\t4\t0\t0\t0\t0\t1\t1\t4\t0\t3\t1\t2\t1\t0\t1\t2\t1\t1\t0\t0\t1\t2\t1\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t6\t0\t0\t0\t1\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t2\t0\t0\t0\t0\t2\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t4\t3\t0\t0\t3\t0\t0\t2\t0\t1\t0\t2\t0\t0\t5\t2\t5\t4\t0\t0\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t13\t1\t0\t0\t0\t0\t0\t0\t13\t1\t0\t0\t1\t0\t0\t1\t0\t0\t10\t0\t0\t1\t9\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t6\t6\t0\t0\t1\t0\t0\t2\t0\t0\t0\t5\t3\t0\t0\t7\t0\t0\t0\t0\t0\t3\t1\t1\t1\t0\t0\t0\t9\t0\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t3\t0\t4\t0\t0\t0\t1\t0\t3\t0\t1\t2\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t6\t1\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t1\t1\t0\t0\t1\t6\t4\t0\t0\t2\t2\t0\t0\t0\t1\t0\t0\t2\t0\t0\t8\t7\t1\t0\t0\t0\t7\t0\t0\t0\t0\t0\t0\t0\t3\t3\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t1\t5\t0\t0\t2\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t3\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t4\t0\t0\t6\t0\t0\t0\t0\t5\t1\t3\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t4\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t1\t0\t0\t0\t0\t0\t9\t2\t0\t0\t1\t0\t0\t0\t0\t0\t2\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t1\t0\t0\t0\t21\t1\t0\t2\t1\t0\t2\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t3\t1\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t4\t2\t0\t0\t1\t0\t0\t0\t0\t4\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t6\t1\t1\t0\t3\t0\t0\t0\t0\t3\t3\t1\t0\t3\t1\t0\t0\t3\t0\t1\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t6\t0\t0\t0\t1\t5\t3\t7\t0\t3\t3\t3\t0\t0\t0\t0\t0\t2\t0\t1\t9\t2\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t5\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t2\t7\t0\t1\t0\t0\t5\t0\t0\t5\t1\t4\t0\t10\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t4\t1\t1\t0\t8\t0\t0\t0\t11\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t1\t0\t0\t6\t0\t0\t4\t3\t6\t1\t2\t0\t0\t4\t0\t0\t0\t0\t0\t0\t1\t3\t4\t9\t0\t4\t1\t5\t0\t0\t5\t1\t0\t0\t0\t0\t0\t1\t8\t0\t0\t0\t0\t13\t0\t2\t6\t0\t0\t0\t0\t1\t24\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t7\t0\t9\t0\t1\t1\t2\t5\t0\t0\t0\t1\t0\t1\t3\t0\t1\t0\t1\t1\t0\t0\t0\t0\t0\t0\t8\t0\t0\t0\t0\t3\t0\t0\t0\t0\t7\t0\t8\t2\t12\t4\t0\t0\t0\t4\t7\t6\t0\t20\t0\t1\t3\t1\t0\t4\t15\t2\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t1\t4\t0\t0\t0\t0\t0\t0\t21\t4\t0\t0\t0\t0\t4\t4\t10\t0\t10\t1\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t2\t3\t8\t0\t1\t3\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t10\t0\t0\t10\t0\t0\t6\t0\t0\t0\t0\t0\t0\t0\t0\t15\t1\t0\t0\t1\t0\t0\t0\t0\t4\t0\t0\t0\t0\t7\t0\t0\t0\t0\t0\t0\t0\t2\t1\t0\t5\t0\t0\t0\t0\t4\t2\t0\t0\t1\t1\t18\t1\t2\t0\t6\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t1\t8\t3\t8\t1\t0\t0\t3\t1\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t1\t7\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t1\t0\t10\t0\t1\t0\t1\t8\t12\t3\t0\t0\t12\t0\t0\t0\t5\t1\t1\t0\t0\t0\t0\t1\t1\t3\t0\t0\t0\t0\t0\t3\t1\t0\t3\t4\t0\t1\t0\t6\t0\t0\t0\t3\t1\t0\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t4\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t6\t1\t0\t4\t0\t0\t0\t4\t1\t1\t0\t0\t0\t0\t8\t4\t2\t0\t0\t0\t2\t4\t0\t0\t1\t15\t3\t0\t1\t1\t0\t2\t3\t4\t0\t0\t2\t0\t1\t0\t8\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t8\t0\t0\t0\t5\t2\t0\t0\t0\t0\t0\t0\t4\t0\t3\t1\t0\t0\t1\t0\t0\t0\t0\t1\t1\t0\t0\t0\t0\t0\t0\t1\t0\t1\t4\t1\t0\t4\t0\t3\t0\t0\t0\t1\t5\t0\t5\t3\t0\t0\t4\t0\t0\t0\t3\t2\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t8\t8\t0\t0\t0\t0\t0\t1\t0\t0\t0\t2\t1\t0\t0\t1\t0\t0\t0\t4\t12\t1\t0\t0\t1\t15\t8\t0\t1\t0\t7\t0\t0\t0\t1\t1\t1\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t4\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t3\t0\t0\t10\t1\t0\t0\t2\t5\t1\t0\t0\t1\t0\t0\t0\t2\t0\t3\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t2\t1\t0\t0\t0\t4\t1\t0\t3\t0\t0\t2\t0\t0\t0\t2\t2\t0\t0\t0\t0\t4\t3\t0\t0\t0\t1\t0\t0\t0\t0\t8\t0\t1\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t1\t0\t0\t1\t0\t0\t4\t2\t0\t0\t2\t1\t7\t0\t2\t15\t0\t0\t0\t0\t0\t0\t2\t1\t0\t0\t1\t0\t0\t0\t0\t0\t2\t4\t2\t12\t0\t5\t0\t0\t0\t1\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t2\t2\t0\t0\n'
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/test.matrix
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/test.matrix Mon Jun 03 14:55:24 2019 -0400
b
b'@@ -0,0 +1,501 @@\n+\tP1_B1_CCATCA\tP1_B1_CCACAA\tP1_B1_GTATGC\tP1_B1_GGTGTA\tP1_B1_AGGACA\tP1_B1_ACTCTG\tP1_B1_TGTCTG\tP1_B1_CGTTCA\tP1_B1_AGGATC\tP1_B1_GCTTCA\tP1_B1_AGGAAG\tP1_B1_GTTGAG\tP1_B1_CTCAGA\tP1_B1_AGCGAA\tP1_B1_AGAACG\tP1_B1_ACGTGA\tP1_B1_TTCGAC\tP1_B1_GTTAGG\tP1_B1_GAAGGA\tP1_B1_GTGAAG\tP1_B1_ATCGTG\tP1_B1_AGGCTA\tP1_B1_TCTAGG\tP1_B1_GTATCG\tP1_B1_TTGCAC\tP1_B1_CGCTAA\tP1_B1_GGTATG\tP1_B1_GCTAAG\tP1_B1_TGGTTG\tP1_B1_CGGTTA\tP1_B1_CTAACG\tP1_B1_CACGTA\tP1_B1_TCAACG\tP1_B1_TGAACC\tP1_B1_GGTTAG\tP1_B1_ATCAGC\tP1_B1_TGTTCC\tP1_B1_AACGAG\tP1_B1_AGCTAG\tP1_B1_TCACAG\tP1_B1_GTAACC\tP1_B1_ACCAAC\tP1_B1_ATGTCG\tP1_B1_AAGTGC\tP1_B1_GCATGA\tP1_B1_GTCTCA\tP1_B1_TTGCTG\tP1_B1_CTAGGA\tP1_B1_GCAGAA\tP1_B1_TACGCA\tP1_B1_TTGCGA\tP1_B1_GCTTAC\tP1_B1_GGTAAC\tP1_B1_TGTTGG\tP1_B1_TAGGAC\tP1_B1_CATTGG\tP1_B1_TAGCTC\tP1_B1_TAACGG\tP1_B1_CTGCTA\tP1_B1_TACAGG\tP1_B1_TTCCAG\tP1_B1_GATACG\tP1_B1_TTGGAG\tP1_B1_CACCAA\tP1_B1_CGATGA\tP1_B1_ACGGTA\tP1_B1_CAATGC\tP1_B1_GAGGTA\tP1_B1_TAGTGG\tP1_B1_CCAATC\tP1_B1_ATCGCA\tP1_B1_GAAGAC\tP1_B1_GTGACA\tP1_B1_CTGTTG\tP1_B1_CACTTC\tP1_B1_CGTCTA\tP1_B1_TGAAGG\tP1_B1_CAGGAA\tP1_B1_GCAACA\tP1_B1_GTGATC\tP1_B1_CCGTAA\tP1_B1_AACACC\tP1_B1_AGCTCA\tP1_B1_GGCTTA\tP1_B1_GAGCAA\tP1_B1_GCCATA\tP1_B1_GATCTG\tP1_B1_GAATGG\tP1_B1_TGTACG\tP1_B1_GCATTC\tP1_B1_ACAAGC\tP1_B1_GGAATC\tP1_B1_ACTTCG\tP1_B1_GCTCTA\tP1_B1_CGATTG\tP1_B1_ATCACG\tP1_B1_GGTAGA\tP1_B1_ATGAGG\tP1_B1_GAGTGA\tP1_B1_ACCAGA\tP1_B1_TGCAAC\tP1_B1_CGTTAC\tP1_B1_TTCTCG\tP1_B1_ACCATG\tP1_B1_ATGCAG\tP1_B1_TCATCC\tP1_B1_CCTGAA\tP1_B1_ACAGTG\tP1_B1_GTGGAA\tP1_B1_GACGAA\tP1_B1_AGTGCA\tP1_B1_AGCTTC\tP1_B1_ATCCGA\tP1_B1_ATGCTC\tP1_B1_CCTATG\tP1_B1_GGACAA\tP1_B1_GATTGC\tP1_B1_ATGGAC\tP1_B1_TGGTGA\tP1_B1_ACTCAC\tP1_B1_ACAGGA\tP1_B1_AGACTC\tP1_B1_AACCTC\tP1_B1_GCAATG\tP1_B1_ATACGG\tP1_B1_CCATAG\tP1_B1_AAGCCA\tP1_B1_AGTACC\tP1_B1_GAATCC\tP1_B1_TATCCG\tP1_B1_AGTAGG\tP1_B1_CGTAAG\tP1_B1_TTGTGC\tP1_B1_TGTAGC\tP1_B1_CAGAAG\tP1_B1_CTATCC\tP1_B1_TTACGC\tP1_B1_TGCAGA\tP1_B1_GTACTC\tP1_B1_ATTGCG\tP1_B1_ATGACC\tP1_B1_TACCGA\tP1_B1_AGTGTC\tP1_B1_GAGTTG\tP1_B1_TGTCGA\tP1_B1_GCGTTA\tP1_B1_ATTCGC\tP1_B1_TCTTGC\tP1_B1_AAGGTG\tP1_B1_CATGCA\tP1_B1_ACGTAC\tP1_B1_CTAGTG\tP1_B1_ACATGG\tP1_B1_GTACCA\tP1_B1_CGAACA\tP1_B1_AGACAG\tP1_B1_GGATAC\tP1_B1_GGATCA\tP1_B1_CGCATA\tP1_B1_AACTGG\tP1_B1_CTAGAC\tP1_B1_CTTCGA\tP1_B1_ACAGAC\tP1_B1_CCAGTA\tP1_B1_CATGTC\tP1_B1_TTCACC\tP1_B1_TACTCC\tP1_B1_TTGGCA\tP1_B1_AAGCAC\tP1_B1_AGATGC\tP1_B1_TACCAC\tP1_B1_CCTACA\tP1_B1_CTCGAA\tP1_B1_GATCGA\tP1_B1_TGAGGA\tP1_B1_TTGGTC\tP1_B1_CCTTGA\tP1_B1_CCGATA\tP1_B1_ATCCAC\tP1_B1_TGATCG\tP1_B1_CTAAGC\tP1_B1_ACGTTG\tP1_B1_AGACCA\tP1_B1_TCCGAA\tP1_B1_TATCGC\tP1_B1_ACTCGA\tP1_B1_CTCATG\tP1_B1_GTACAG\tP1_B1_GACAGA\tP1_B1_CACTCA\tP1_B1_GACAAC\tP1_B1_ATCTCC\tP1_B2_TGAGGA\tP1_B2_CCGTAA\tP1_B2_GTGAAG\tP1_B2_GACAGA\tP1_B2_AGTAGG\tP1_B2_TATCGC\tP1_B2_ATTCGC\tP1_B2_CTAGAC\tP1_B2_GTATCG\tP1_B2_TCATCC\tP1_B2_CCTATG\tP1_B2_GGACAA\tP1_B2_CCAATC\tP1_B2_AAGCAC\tP1_B2_CGTTAC\tP1_B2_TAGCTC\tP1_B2_TGCAAC\tP1_B2_GCATTC\tP1_B2_GCAGAA\tP1_B2_AGACCA\tP1_B2_AGTACC\tP1_B2_TTGCTG\tP1_B2_TTGCAC\tP1_B2_TAACGG\tP1_B2_ACGTTG\tP1_B2_GTGGAA\tP1_B2_GGTTAG\tP1_B2_GCTTAC\tP1_B2_GCCATA\tP1_B2_TCAACG\tP1_B2_CCATAG\tP1_B2_ATGCTC\tP1_B2_TTGTGC\tP1_B2_TTGGCA\tP1_B2_ATCACG\tP1_B2_AACACC\tP1_B2_CATGCA\tP1_B2_TTCACC\tP1_B2_GAAGGA\tP1_B2_GAAGAC\tP1_B2_CGCATA\tP1_B2_TGAACC\tP1_B2_TTGGAG\tP1_B2_TTCCAG\tP1_B2_AAGGTG\tP1_B2_GTTAGG\tP1_B2_AGCTTC\tP1_B2_GTTGAG\tP1_B2_TGTCGA\tP1_B2_TCACAG\tP1_B2_CTCAGA\tP1_B2_GTATGC\tP1_B2_GTAACC\tP1_B2_CTAGGA\tP1_B2_ATGACC\tP1_B2_AAGCCA\tP1_B2_ACCAGA\tP1_B2_GTCTCA\tP1_B2_GAGTGA\tP1_B2_TCTTGC\tP1_B2_CCTGAA\tP1_B2_GGTATG\tP1_B2_ACCAAC\tP1_B2_ATGGAC\tP1_B2_TAGTGG\tP1_B2_CACTCA\tP1_B2_CTAGTG\tP1_B2_CGGTTA\tP1_B2_CAGGAA\tP1_B2_AGGATC\tP1_B2_TTCTCG\tP1_B2_AGCTCA\tP1_B2_GTGATC\tP1_B2_ATCCAC\tP1_B2_GGCTTA\tP1_B2_ACGTAC\tP1_B2_ACTCGA\tP1_B2_GCAATG\tP1_B2_TGTACG\tP1_B2_ACAGAC\tP1_B2_GAGCAA\tP1_B2_ACATGG\tP1_B2_AGCGAA\tP1_B2_TTGGTC\tP1_B2_CTGTTG\tP1_B2_GACGAA\tP1_B2_TGAAGG\tP1_B2_ATTGCG\tP1_B2_GGATCA\tP1_B2_GTACTC\tP1_B2_GAGGTA\tP1_B2_ATCGCA\tP1_B2_CTATCC\tP1_B2_TACCAC\tP1_B2_TGTCTG\tP1_B2_CCACAA\tP1_B2_TACCGA\tP1_B2_AGAACG\tP1_B2_CGTCTA\tP1_B2_ATCGTG\tP1_B2_GAGTTG\tP1_B2_ATCCGA\tP1_B2_AGACAG\tP1_B2_CCGATA\tP1_B2_TGTTCC\tP1_B2_ACTTCG\tP1_B2_TACGCA\tP1_B2_GATACG\tP1_B2_CGATTG\tP1_B2_GGTAAC\tP1_B2_CGCTAA\tP1_B2_ACCATG\tP1_B2_TAGGAC\tP1_B2_CTAACG\tP'..b'\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t0\t0\t0\t10\t0\t166\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t63\t95\t0\t0\t0\t0\t0\t0\t0\t0\t0\t40\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t10\t0\t17\t0\t0\t55\t0\t0\t0\t0\t0\t0\t0\t72\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t0\t3\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t9\t1\t0\t3\t0\t23\t1\t0\t0\t1\t0\t0\t0\t0\t0\t51\t0\t0\t0\t0\t0\t0\t9\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t171\t0\t0\t0\t0\t1\t0\t0\t41\t0\t0\t0\t0\t0\t0\t8\t18\t0\t1\t54\t0\t0\t0\t2\t0\t1\t1\t0\t2\t0\t0\t0\t0\t0\t0\t2\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t18\t17\t8\t0\t0\t1\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t7\t0\t0\t0\t146\t1\t27\t0\t10\t17\t0\t0\t14\t0\t0\t0\t0\t0\t0\t30\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t5\t5\t0\t0\t10\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t64\t0\t1\t0\t0\t0\t0\t0\t0\t9\t0\t1\t0\t49\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t15\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t3\t29\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\n+GENE499\t0\t1\t0\t0\t0\t0\t2\t0\t29\t0\t0\t6\t0\t1\t0\t0\t0\t0\t1\t22\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t1\t1\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t36\t35\t0\t0\t0\t0\t0\t19\t0\t2\t20\t0\t0\t0\t9\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t23\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t1\t11\t0\t0\t0\t1\t0\t27\t0\t0\t49\t0\t0\t0\t2\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t18\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t22\t0\t0\t0\t0\t0\t0\t0\t0\t3\t20\t2\t0\t0\t0\t0\t0\t0\t0\t1\t0\t26\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t6\t0\t0\t0\t0\t0\t0\t0\t25\t0\t0\t0\t2\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t1\t0\t89\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t2\t0\t0\t0\t0\t87\t0\t0\t0\t0\t0\t0\t3\t0\t8\t0\t0\t1\t0\t14\t0\t0\t0\t0\t1\t0\t0\t0\t2\t0\t0\t0\t1\t0\t1\t0\t0\t73\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t1\t0\t0\t0\t7\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t1\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t9\t9\t0\t0\t0\t0\t1\t0\t0\t75\t0\t1\t0\t0\t0\t0\t6\t0\t0\t0\t2\t1\t0\t0\t0\t0\t0\t4\t0\t1\t0\t1\t0\t0\t0\t0\t9\t0\t0\t0\t12\t107\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t32\t0\t0\t0\t0\t0\t0\t17\t1\t0\t0\t0\t0\t27\t0\t0\t1\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t12\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t31\t0\t0\t2\t0\t2\t8\t0\t1\t0\t1\t0\t0\t0\t9\t0\t0\t0\t0\t7\t0\t9\t0\t0\t0\t0\t22\t10\t2\t0\t0\t19\t0\t0\t32\t0\t2\t0\t0\t1\t0\t0\t0\t0\t11\t0\t0\t0\t2\t25\t35\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t20\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t129\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t19\t0\t0\t0\t12\t1\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t67\t0\t0\t17\t9\t1\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t1\t3\t0\t0\t0\t0\t23\t0\t0\t2\t0\t0\t0\t0\t1\t0\t2\t0\t101\t0\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t42\t0\t0\t0\t0\t1\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t4\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t1\t0\t0\t0\t0\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t48\t0\t0\t0\t3\t0\t1\t0\t5\t0\t2\t0\t56\t0\t0\t0\t0\t0\t0\t0\t6\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t39\t0\t0\t42\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t2\t0\t0\t0\t0\t0\t0\t0\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\n+GENE500\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t33\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t146\t0\t0\t0\t1\t1\t0\t0\t0\t0\t2\t0\t0\t0\t28\t0\t0\t0\t0\t16\t0\t0\t0\t0\t9\t0\t0\t0\t0\t0\t0\t0\t0\t3\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t11\t0\t0\t0\t1\t142\t2\t3\t0\t0\t2\t0\t0\t17\t0\t0\t3\t54\t0\t0\t8\t0\t0\t0\t0\t0\t0\t0\t3\t56\t0\t0\t0\t0\t1\t0\t0\t0\t2\t0\t14\t0\t0\t8\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t6\t0\t0\t0\t3\t0\t0\t6\t4\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t11\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t39\t0\t0\t0\t0\t0\t0\t0\t0\t11\t0\t0\t2\t5\t0\t28\t0\t0\t0\t0\t0\t0\t0\t54\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t42\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t12\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t18\t0\t0\t0\t0\t0\t0\t5\t56\t0\t0\t0\t0\t0\t0\t0\t0\t76\t0\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t23\t22\t0\t4\t0\t0\t8\t0\t3\t1\t0\t0\t0\t6\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t1\t0\t2\t0\t0\t0\t0\t0\t14\t4\t0\t0\t0\t0\t0\t0\t0\t1\t12\t2\t0\t11\t0\t0\t2\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t8\t0\t16\t0\t0\t0\t0\t0\t1\t10\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t22\t7\t0\t1\t3\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t6\t1\t1\t0\t5\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t1\t0\t24\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t6\t0\t0\t0\t0\t0\t0\t36\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t7\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t0\t0\t0\t12\t0\t0\t0\t1\t0\t75\t0\t9\t0\t0\t0\t1\t0\t2\t0\t0\t26\t28\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t37\t0\t0\t15\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t6\t0\t0\t0\t0\t0\t0\t0\t0\t22\t0\t36\t0\t0\t0\t0\t0\t0\t0\t31\t0\t0\t0\t37\t0\t1\t0\t1\t1\t1\t1\t0\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t70\t0\t5\t46\t0\t0\t0\t0\t0\t0\t7\t0\t0\t0\t4\t0\t0\t0\t0\t0\t4\t0\t15\t1\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t9\t0\t0\t0\t0\t0\t0\t0\t0\t8\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t2\t0\t1\t67\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t140\t0\t0\t31\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t25\t0\t3\t0\t0\t0\t0\t0\t0\t0\t20\t0\t11\t0\t5\t0\t0\t1\t0\t0\t0\t0\t114\t2\t0\t0\t0\t0\t0\t17\t0\t0\t0\t0\t0\t0\t0\t8\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t50\t0\t0\t0\t0\t0\t0\t0\t10\t0\t0\n'
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/test.pdf
b
Binary file test-data/test.pdf has changed
b
diff -r 582b7bd4ae4c -r 253c9448f524 test-data/test.table
--- a/test-data/test.table Thu Jan 24 09:52:58 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
b
b'@@ -1,176 +0,0 @@\n-P1_B1_AACCTC\tP1_B1_AACGAG\tP1_B1_AAGCCA\tP1_B1_ACAAGC\tP1_B1_ACAGAC\tP1_B1_ACAGGA\tP1_B1_ACAGTG\tP1_B1_ACCAAC\tP1_B1_ACCAGA\tP1_B1_ACCATG\tP1_B1_ACGTAC\tP1_B1_ACGTGA\tP1_B1_ACGTTG\tP1_B1_ACTCAC\tP1_B1_ACTCGA\tP1_B1_ACTCTG\tP1_B1_ACTTCG\tP1_B1_AGACAG\tP1_B1_AGACCA\tP1_B1_AGACTC\tP1_B1_AGCTAG\tP1_B1_AGCTCA\tP1_B1_AGCTTC\tP1_B1_AGGAAG\tP1_B1_AGGACA\tP1_B1_AGGATC\tP1_B1_AGTGCA\tP1_B1_AGTGTC\tP1_B1_ATCACG\tP1_B1_ATGTCG\tP1_B1_ATTGCG\tP1_B1_CACCAA\tP1_B1_CACTCA\tP1_B1_CACTTC\tP1_B1_CAGAAG\tP1_B1_CATGCA\tP1_B1_CATGTC\tP1_B1_CCACAA\tP1_B1_CCATAG\tP1_B1_CGATGA\tP1_B1_CGATTG\tP1_B1_CGTCTA\tP1_B1_CTAAGC\tP1_B1_CTAGAC\tP1_B1_CTAGGA\tP1_B1_CTAGTG\tP1_B1_CTATCC\tP1_B1_CTCAGA\tP1_B1_CTCATG\tP1_B1_CTGTTG\tP1_B1_CTTCGA\tP1_B1_GAAGAC\tP1_B1_GAAGGA\tP1_B1_GAATCC\tP1_B1_GAATGG\tP1_B1_GACAAC\tP1_B1_GACAGA\tP1_B1_GACGAA\tP1_B1_GAGTGA\tP1_B1_GAGTTG\tP1_B1_GATACG\tP1_B1_GATCGA\tP1_B1_GATCTG\tP1_B1_GCAACA\tP1_B1_GGACAA\tP1_B1_GGTAAC\tP1_B1_GTACAG\tP1_B1_GTACCA\tP1_B1_GTACTC\tP1_B1_GTCTCA\tP1_B1_GTGAAG\tP1_B1_GTGACA\tP1_B1_GTGATC\tP1_B1_GTGGAA\tP1_B1_GTTGAG\tP1_B1_TAACGG\tP1_B1_TAGGAC\tP1_B1_TAGTGG\tP1_B1_TCACAG\tP1_B1_TCATCC\tP1_B1_TCCGAA\tP1_B1_TCTTGC\tP1_B1_TGAACC\tP1_B1_TGAAGG\tP1_B1_TGAGGA\tP1_B1_TGCAAC\tP1_B1_TGCAGA\tP1_B1_TGGTGA\tP1_B1_TGGTTG\tP1_B1_TGTACG\tP1_B1_TGTCGA\tP1_B1_TGTCTG\tP1_B1_TTCACC\tP1_B1_TTCCAG\tP1_B1_TTCTCG\tP1_B1_TTGTGC\tP1_B2_AACACC\tP1_B2_AACTGG\tP1_B2_AAGCAC\tP1_B2_AAGGTG\tP1_B2_AAGTGC\tP1_B2_ACATGG\tP1_B2_ACGGTA\tP1_B2_AGAACG\tP1_B2_AGATGC\tP1_B2_AGCGAA\tP1_B2_AGGCTA\tP1_B2_AGTACC\tP1_B2_AGTAGG\tP1_B2_ATACGG\tP1_B2_ATCAGC\tP1_B2_ATCCAC\tP1_B2_ATCCGA\tP1_B2_ATCGCA\tP1_B2_ATCGTG\tP1_B2_ATCTCC\tP1_B2_ATGACC\tP1_B2_ATGAGG\tP1_B2_ATGCAG\tP1_B2_ATGCTC\tP1_B2_ATGGAC\tP1_B2_ATTCGC\tP1_B2_CAATGC\tP1_B2_CACGTA\tP1_B2_CAGGAA\tP1_B2_CATTGG\tP1_B2_CCAATC\tP1_B2_CCAGTA\tP1_B2_CCATCA\tP1_B2_CCGATA\tP1_B2_CCGTAA\tP1_B2_CCTACA\tP1_B2_CCTATG\tP1_B2_CCTGAA\tP1_B2_CCTTGA\tP1_B2_CGAACA\tP1_B2_CGCATA\tP1_B2_CGCTAA\tP1_B2_CGGTTA\tP1_B2_CGTAAG\tP1_B2_CGTTAC\tP1_B2_CGTTCA\tP1_B2_CTAACG\tP1_B2_CTCGAA\tP1_B2_CTGCTA\tP1_B2_GAGCAA\tP1_B2_GAGGTA\tP1_B2_GATTGC\tP1_B2_GCAATG\tP1_B2_GCAGAA\tP1_B2_GCATGA\tP1_B2_GCATTC\tP1_B2_GCCATA\tP1_B2_GCGTTA\tP1_B2_GCTAAG\tP1_B2_GCTCTA\tP1_B2_GCTTAC\tP1_B2_GCTTCA\tP1_B2_GGAATC\tP1_B2_GGATAC\tP1_B2_GGATCA\tP1_B2_GGCTTA\tP1_B2_GGTAGA\tP1_B2_GGTATG\tP1_B2_GGTGTA\tP1_B2_GGTTAG\tP1_B2_GTAACC\tP1_B2_GTATCG\tP1_B2_GTATGC\tP1_B2_GTTAGG\tP1_B2_TACAGG\tP1_B2_TACCAC\tP1_B2_TACCGA\tP1_B2_TACGCA\tP1_B2_TACTCC\tP1_B2_TAGCTC\tP1_B2_TATCCG\tP1_B2_TATCGC\tP1_B2_TCAACG\tP1_B2_TCTAGG\tP1_B2_TGATCG\tP1_B2_TGTAGC\tP1_B2_TGTTCC\tP1_B2_TGTTGG\tP1_B2_TTACGC\tP1_B2_TTCGAC\tP1_B2_TTGCAC\tP1_B2_TTGCGA\tP1_B2_TTGCTG\tP1_B2_TTGGAG\tP1_B2_TTGGCA\tP1_B2_TTGGTC\tP1_B3_AACCTC\tP1_B3_AACGAG\tP1_B3_AAGCCA\tP1_B3_ACAAGC\tP1_B3_ACAGAC\tP1_B3_ACAGGA\tP1_B3_ACAGTG\tP1_B3_ACCAAC\tP1_B3_ACCAGA\tP1_B3_ACCATG\tP1_B3_ACGTAC\tP1_B3_ACGTGA\tP1_B3_ACGTTG\tP1_B3_ACTCAC\tP1_B3_ACTCGA\tP1_B3_ACTCTG\tP1_B3_ACTTCG\tP1_B3_AGACAG\tP1_B3_AGACCA\tP1_B3_AGACTC\tP1_B3_AGCTAG\tP1_B3_AGCTCA\tP1_B3_AGCTTC\tP1_B3_AGGAAG\tP1_B3_AGGACA\tP1_B3_AGGATC\tP1_B3_AGTGCA\tP1_B3_AGTGTC\tP1_B3_ATCACG\tP1_B3_ATGTCG\tP1_B3_ATTGCG\tP1_B3_CACCAA\tP1_B3_CACTCA\tP1_B3_CACTTC\tP1_B3_CAGAAG\tP1_B3_CATGCA\tP1_B3_CATGTC\tP1_B3_CCACAA\tP1_B3_CCATAG\tP1_B3_CGATGA\tP1_B3_CGATTG\tP1_B3_CGTCTA\tP1_B3_CTAAGC\tP1_B3_CTAGAC\tP1_B3_CTAGGA\tP1_B3_CTAGTG\tP1_B3_CTATCC\tP1_B3_CTCAGA\tP1_B3_CTCATG\tP1_B3_CTGTTG\tP1_B3_CTTCGA\tP1_B3_GAAGAC\tP1_B3_GAAGGA\tP1_B3_GAATCC\tP1_B3_GAATGG\tP1_B3_GACAAC\tP1_B3_GACAGA\tP1_B3_GACGAA\tP1_B3_GAGTGA\tP1_B3_GAGTTG\tP1_B3_GATACG\tP1_B3_GATCGA\tP1_B3_GATCTG\tP1_B3_GCAACA\tP1_B3_GGACAA\tP1_B3_GGTAAC\tP1_B3_GTACAG\tP1_B3_GTACCA\tP1_B3_GTACTC\tP1_B3_GTCTCA\tP1_B3_GTGAAG\tP1_B3_GTGACA\tP1_B3_GTGATC\tP1_B3_GTGGAA\tP1_B3_GTTGAG\tP1_B3_TAACGG\tP1_B3_TAGGAC\tP1_B3_TAGTGG\tP1_B3_TCACAG\tP1_B3_TCATCC\tP1_B3_TCCGAA\tP1_B3_TCTTGC\tP1_B3_TGAACC\tP1_B3_TGAAGG\tP1_B3_TGAGGA\tP1_B3_TGCAAC\tP1_B3_TGCAGA\tP1_B3_TGGTGA\tP1_B3_TGGTTG\tP1_B3_TGTACG\tP1_B3_TGTCGA\tP1_B3_TGTCTG\tP1_B3_TTCACC\tP1_B3_TTCCAG\tP1_B3_TTCTCG\tP1_B3_TTGTGC\tP1_B4_AACACC\tP1_B4_AACTGG\tP1_B4_AAGCAC\tP1_B4_AAGGTG\tP1_B4_AAGTGC\tP1_B4_ACATGG\tP1_B4_ACGGTA\tP1_B4_AGAACG\tP1_B4_AGATGC\tP1_B4_AGCGAA\tP1_B4_AGGCTA\tP1_B4_AGTACC\tP1_B4_AGTAGG\tP1_B4_ATACGG\tP1_B4_ATCAGC\tP1_B4_ATCCAC\tP1_B4_ATCCGA\tP1_B4_ATCGCA\tP1'..b'\t0\t0\t0\t0\t0\t1\t7\t0\t0\t0\t3\t0\t1\t0\t55\t0\t9\t0\t0\t0\t0\t3\t5\t5\t4\t0\t3\t0\t1\t0\t0\t0\t0\t0\t0\t14\t0\t0\t47\t0\t0\t8\t1\t0\t26\t0\t6\t24\t0\t6\t6\t0\t0\t4\t19\t0\t1\t4\t0\t0\t9\t0\t11\t1\t19\t15\t0\t10\t39\t0\t0\t4\t0\t14\t1\t1\t0\t3\t3\t0\t0\t8\t1\t0\t9\t12\t0\t1\t15\t0\t30\t1\t2\t1\t5\t21\t2\t7\t0\t6\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t10\t0\t1\t0\t23\t0\t9\t2\t1\t4\t10\t0\t8\t1\t3\t0\t0\t0\t2\t0\t0\t0\t0\t2\t1\t1\t0\t6\t4\t0\t0\t0\t12\t1\t0\t2\t7\t34\t2\t0\t11\t4\t1\t0\t0\t1\t1\t4\t3\t0\t2\t7\t0\t0\t0\t0\t0\t12\t0\t0\t0\t0\t22\t14\t10\t0\t6\t2\t0\t9\t1\t0\t1\t0\t0\t7\t5\t2\t0\t0\t1\t0\t0\t0\t2\t14\t4\t7\t6\t2\t0\t0\t1\t0\t9\t0\t2\t9\t0\t6\t1\t0\t7\t10\t2\t0\t1\t0\t6\t2\t2\t16\t0\t0\t0\t4\t4\t1\t0\t1\t2\t1\t0\t19\t0\t0\t5\t1\t1\t3\t2\t1\t1\t0\t1\t0\t11\t0\t0\t0\t0\t0\t8\t2\t4\t10\t0\t2\t0\t9\t8\t0\t4\t4\t8\t0\t6\t0\t0\t10\t0\t10\t0\t1\t0\t0\t0\t0\t0\t0\t3\t0\t1\t3\t1\t0\t19\t8\t7\t7\t0\t0\t5\t0\t0\t1\t1\t0\t16\t0\t0\t0\t0\t12\t1\t0\t1\t0\t3\t0\t1\t1\t1\t0\t0\t1\t1\t0\t3\t0\t2\t5\t3\t0\t0\t1\t0\t0\t2\t0\t12\t0\t3\t5\t3\t1\t0\t5\t1\t2\t3\t0\t0\t3\t1\t4\t2\t0\t0\t4\t2\t11\t3\t13\t9\t0\t0\t4\t0\t4\t0\t0\t0\t3\t1\t2\t9\t0\t0\t3\t11\t1\t6\t0\t0\t2\t7\t0\t0\t3\t6\t0\t9\t0\t0\t0\t0\t3\t10\t0\t2\t0\t1\t0\t0\t0\t4\t0\t4\t0\t0\n-ENSDARG00000104458\t0\t0\t0\t0\t0\t0\t0\t1\t3\t0\t0\t0\t10\t0\t0\t3\t0\t1\t1\t2\t0\t0\t1\t0\t0\t3\t0\t2\t0\t1\t4\t0\t8\t0\t3\t0\t0\t0\t0\t7\t0\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t7\t0\t0\t0\t4\t3\t0\t1\t0\t0\t2\t0\t1\t0\t6\t8\t0\t0\t2\t2\t0\t3\t0\t0\t2\t0\t0\t2\t2\t0\t5\t0\t0\t0\t0\t0\t0\t1\t2\t0\t0\t1\t6\t0\t0\t0\t2\t0\t0\t0\t5\t0\t1\t1\t2\t0\t0\t4\t0\t1\t0\t1\t1\t0\t2\t0\t0\t1\t1\t0\t1\t0\t3\t0\t0\t0\t0\t1\t5\t0\t0\t1\t0\t1\t3\t0\t4\t3\t0\t5\t3\t0\t4\t5\t2\t0\t0\t4\t2\t0\t0\t9\t0\t1\t0\t0\t1\t0\t11\t0\t0\t2\t4\t0\t3\t0\t4\t7\t0\t9\t0\t3\t0\t0\t1\t15\t3\t0\t0\t6\t2\t0\t8\t0\t0\t0\t0\t0\t0\t0\t1\t5\t0\t0\t4\t2\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t8\t1\t0\t5\t0\t0\t0\t0\t2\t4\t0\t0\t5\t0\t7\t8\t0\t4\t0\t4\t0\t0\t0\t5\t0\t2\t3\t0\t0\t10\t0\t0\t9\t4\t2\t0\t0\t0\t0\t0\t0\t1\t0\t4\t3\t0\t0\t2\t0\t11\t2\t1\t0\t0\t0\t2\t1\t1\t0\t0\t5\t2\t0\t1\t1\t0\t0\t4\t2\t0\t0\t8\t0\t10\t0\t0\t0\t0\t0\t2\t0\t0\t12\t0\t3\t0\t0\t2\t10\t1\t0\t2\t0\t0\t9\t6\t2\t3\t2\t1\t1\t0\t2\t0\t0\t2\t0\t0\t4\t0\t0\t5\t0\t0\t0\t2\t1\t5\t0\t0\t2\t1\t0\t12\t0\t1\t5\t4\t0\t0\t0\t0\t5\t1\t0\t0\t1\t0\t1\t7\t0\t4\t0\t2\t1\t0\t0\t0\t1\t2\t2\t0\t9\t0\t1\t0\t1\t0\t1\t0\t0\t0\t0\t3\t0\t2\t2\t5\t0\t1\t0\t12\t1\t8\t0\t0\t0\t0\t6\t2\t3\t4\t0\t0\t0\t6\t0\t0\t0\t0\t0\t0\t9\t0\t0\t18\t0\t0\t1\t2\t0\t9\t3\t4\t10\t1\t4\t1\t0\t0\t0\t3\t0\t0\t9\t0\t1\t1\t0\t6\t2\t7\t5\t0\t3\t7\t0\t0\t7\t0\t5\t0\t5\t0\t0\t0\t0\t0\t3\t0\t0\t4\t1\t0\t2\t3\t0\t12\t0\t3\t3\t1\t7\t1\t3\t5\t3\t3\t0\t0\t0\t1\t1\t0\t2\t0\t0\t2\t1\t0\t0\t6\t0\t6\t0\t0\t1\t2\t0\t3\t1\t2\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t2\t0\t0\t0\t0\t0\t0\t5\t0\t0\t2\t0\t5\t0\t0\t4\t2\t0\t1\t0\t4\t0\t2\t0\t1\t1\t7\t0\t0\t0\t0\t0\t14\t0\t2\t0\t2\t7\t5\t3\t0\t7\t1\t0\t3\t0\t0\t1\t0\t0\t7\t1\t5\t1\t0\t0\t0\t3\t0\t2\t7\t0\t1\t2\t0\t0\t0\t0\t0\t5\t0\t0\t2\t1\t5\t0\t0\t8\t6\t0\t0\t0\t3\t2\t0\t0\t8\t0\t0\t0\t1\t0\t0\t1\t2\t0\t0\t0\t10\t0\t0\t3\t2\t0\t0\t2\t9\t0\t0\t0\t1\t4\t0\t0\t1\t1\t0\t2\t0\t1\t8\t1\t5\t0\t4\t2\t0\t4\t4\t5\t0\t2\t0\t0\t0\t1\t2\t0\t0\t0\t0\t1\t0\t0\t0\t2\t0\t0\t0\t1\t1\t6\t2\t4\t4\t0\t0\t1\t0\t0\t0\t2\t0\t5\t0\t1\t0\t1\t1\t2\t0\t3\t1\t2\t0\t0\t0\t0\t0\t0\t0\t1\t0\t1\t0\t2\t1\t4\t0\t2\t2\t0\t0\t1\t0\t1\t0\t5\t1\t0\t0\t0\t4\t3\t0\t1\t0\t2\t2\t0\t4\t1\t0\t0\t1\t1\t7\t0\t8\t4\t0\t0\t1\t0\t1\t0\t1\t0\t1\t0\t2\t1\t0\t0\t1\t6\t1\t3\t0\t0\t0\t1\t3\t0\t0\t3\t0\t7\t0\t3\t0\t0\t2\t3\t0\t0\t0\t0\t0\t0\t0\t2\t0\t1\t0\t0\n-ENSDARG00000104782\t0\t0\t0\t0\t0\t3\t0\t2\t3\t2\t1\t0\t4\t4\t0\t1\t0\t12\t0\t5\t1\t1\t2\t0\t1\t2\t2\t2\t0\t2\t6\t0\t5\t0\t6\t0\t0\t0\t1\t3\t1\t1\t1\t1\t2\t0\t0\t1\t0\t1\t1\t0\t1\t7\t0\t0\t1\t3\t0\t0\t0\t0\t0\t0\t4\t5\t0\t4\t13\t0\t0\t8\t0\t1\t1\t0\t4\t0\t1\t1\t4\t3\t1\t2\t1\t1\t2\t1\t1\t0\t1\t2\t3\t0\t0\t6\t0\t1\t0\t3\t0\t0\t0\t2\t0\t1\t4\t3\t0\t0\t2\t0\t1\t0\t2\t0\t0\t5\t2\t5\t4\t0\t1\t0\t0\t13\t1\t0\t0\t0\t0\t13\t1\t0\t0\t1\t1\t0\t0\t10\t0\t1\t9\t3\t0\t6\t6\t2\t0\t0\t5\t3\t0\t0\t7\t0\t0\t0\t0\t3\t1\t1\t0\t0\t0\t9\t0\t3\t0\t5\t0\t0\t3\t0\t4\t0\t1\t0\t3\t2\t0\t0\t6\t1\t0\t1\t0\t1\t0\t0\t0\t0\t0\t1\t1\t0\t1\t6\t4\t0\t2\t2\t0\t0\t1\t0\t0\t2\t0\t8\t7\t1\t0\t7\t0\t0\t0\t0\t3\t3\t1\t0\t1\t0\t1\t5\t0\t2\t0\t1\t0\t1\t3\t1\t0\t0\t4\t0\t0\t6\t0\t0\t5\t1\t3\t0\t0\t0\t0\t1\t0\t0\t0\t4\t3\t0\t0\t1\t0\t9\t2\t1\t0\t0\t0\t0\t2\t3\t0\t0\t2\t0\t0\t0\t1\t0\t0\t21\t1\t0\t2\t1\t2\t5\t0\t0\t0\t0\t0\t3\t1\t0\t5\t0\t2\t4\t0\t0\t6\t1\t1\t0\t0\t0\t3\t3\t1\t0\t3\t1\t0\t0\t3\t1\t0\t1\t0\t0\t6\t0\t1\t5\t3\t7\t0\t3\t3\t3\t0\t0\t0\t2\t1\t9\t2\t1\t0\t5\t1\t0\t0\t0\t4\t2\t7\t0\t1\t0\t0\t5\t0\t5\t1\t4\t10\t0\t0\t1\t0\t0\t0\t0\t4\t1\t1\t0\t8\t0\t11\t0\t0\t0\t0\t2\t0\t0\t1\t6\t0\t4\t3\t6\t1\t2\t4\t0\t0\t1\t3\t4\t9\t4\t1\t5\t0\t5\t1\t0\t0\t0\t0\t1\t8\t0\t0\t13\t0\t2\t6\t0\t1\t24\t1\t7\t9\t1\t2\t5\t0\t0\t1\t3\t1\t0\t8\t3\t0\t7\t0\t8\t2\t12\t4\t0\t4\t7\t6\t0\t20\t0\t1\t3\t4\t15\t2\t0\t1\t1\t2\t4\t0\t21\t4\t0\t0\t4\t4\t10\t10\t1\t0\t1\t2\t3\t8\t1\t3\t0\t0\t1\t0\t0\t0\t0\t0\t1\t0\t5\t0\t0\t10\t10\t0\t6\t0\t0\t1\t4\t0\t7\t0\t2\t1\t0\t0\t0\t4\t2\t0\t0\t1\t1\t18\t1\t2\t6\t0\t0\t0\t2\t0\t0\t8\t3\t8\t1\t0\t0\t3\t1\t0\t0\t1\t0\t0\t0\t0\t1\t7\t0\t5\t0\t1\t0\t10\t0\t1\t0\t1\t8\t12\t3\t0\t12\t0\t0\t5\t1\t1\t0\t0\t1\t3\t3\t3\t4\t0\t1\t0\t6\t0\t3\t1\t1\t1\t4\t3\t0\t0\t0\t0\t6\t1\t0\t4\t0\t4\t1\t0\t8\t4\t2\t0\t0\t2\t4\t0\t1\t15\t3\t0\t1\t1\t2\t3\t4\t2\t0\t1\t0\t8\t0\t0\t5\t0\t0\t8\t0\t5\t2\t0\t0\t0\t4\t3\t1\t1\t0\t1\t4\t1\t0\t4\t0\t3\t0\t1\t5\t0\t5\t3\t0\t0\t4\t0\t3\t2\t0\t2\t0\t1\t0\t8\t8\t0\t0\t0\t1\t0\t0\t2\t1\t4\t12\t1\t15\t8\t1\t0\t7\t0\t0\t1\t1\t1\t3\t0\t0\t0\t0\t2\t3\t0\t0\t0\t0\t1\t0\t0\t0\t1\t0\t1\t3\t0\t1\t0\t2\t5\t1\t0\t0\t1\t0\t0\t0\t2\t3\t0\t0\t1\t2\t1\t0\t4\t1\t0\t3\t0\t0\t2\t0\t2\t2\t0\t0\t0\t4\t3\t0\t8\t2\t0\t0\t0\t1\t1\t0\t0\t1\t0\t0\t4\t2\t0\t2\t1\t7\t2\t15\t0\t0\t0\t2\t1\t0\t2\t4\t2\t12\t0\t5\t0\t1\t0\t5\t0\t1\t0\t0\t0\t1\t0\t1\t0\t2\t2\t0\n'