changeset 3:b5c7ba11401d draft

"planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/anndata/ commit dc9d19d1f902f3ed54009cd0e68c8518c284b856"
author iuc
date Mon, 06 Jan 2020 13:45:13 -0500
parents e175d4067b00
children 080eab96d846
files import.xml loompy_to_tsv.py macros.xml modify_loom.py test-data/addlayer1.tsv test-data/addloomout1.loom test-data/addloomout2.loom test-data/addloomout3.loom test-data/addtest.loom test-data/cols.tsv test-data/converted.loom.test test-data/finallayer.tsv test-data/firstlayer.tsv test-data/loomtest.loom test-data/rows.tsv test-data/secondlayer.tsv tsv_to_loompy.py
diffstat 17 files changed, 596 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/import.xml	Thu Dec 12 09:23:27 2019 -0500
+++ b/import.xml	Mon Jan 06 13:45:13 2020 -0500
@@ -1,4 +1,4 @@
-<tool id="anndata_import" name="Import AnnData" version="@VERSION@+@GALAXY_VERSION@">
+<tool id="anndata_import" name="Import Anndata and loom" version="@VERSION@+@GALAXY_VERSION@">
     <description>from different format</description>
     <macros>
         <import>macros.xml</import>
@@ -17,124 +17,155 @@
     </expand>
     <expand macro="version_command"/>
     <command detect_errors="exit_code"><![CDATA[
-#if $in.adata_format == 'mtx'
-mkdir mtx
-    #if $in.tenx.use == 'legacy_10x'
-&& cp '$in.matrix' 'mtx/matrix.mtx'
-&& cp '$in.tenx.genes' 'mtx/genes.tsv'
-&& cp '$in.tenx.barcodes' 'mtx/barcodes.tsv'
-    #else if $in.tenx.use == 'v3_10x'
-&& cp '$in.matrix' 'mtx/matrix.mtx'
-&& gzip 'mtx/matrix.mtx'
-&& cp '$in.tenx.features' 'mtx/features.tsv'
-&& gzip 'mtx/features.tsv'
-&& cp '$in.tenx.barcodes' 'mtx/barcodes.tsv'
-&& gzip 'mtx/barcodes.tsv'
+#if $hd5_format.filetype == 'anndata'
+    #if $hd5_format.in.adata_format == 'mtx'
+        mkdir mtx
+        #if $hd5_format.in.tenx.use == 'legacy_10x'
+            && cp '$hd5_format.in.matrix' 'mtx/matrix.mtx'
+            && cp '$hd5_format.in.tenx.genes' 'mtx/genes.tsv'
+            && cp '$hd5_format.in.tenx.barcodes' 'mtx/barcodes.tsv'
+        #else if $hd5_format.in.tenx.use == 'v3_10x'
+            && cp '$hd5_format.in.matrix' 'mtx/matrix.mtx'
+            && gzip 'mtx/matrix.mtx'
+            && cp '$hd5_format.in.tenx.features' 'mtx/features.tsv'
+            && gzip 'mtx/features.tsv'
+            && cp '$hd5_format.in.tenx.barcodes' 'mtx/barcodes.tsv'
+            && gzip 'mtx/barcodes.tsv'
+        #end if
+        &&
+    #else if $hd5_format.in.adata_format == 'umi_tools'
+        gzip '$hd5_format.in.input'
+        &&
     #end if
-&&
-#else if $in.adata_format == 'umi_tools'
-gzip '$in.input'
-&&
-#end if
+
+    @CMD@
+
+    #if $hd5_format.in.adata_format == 'mtx'
+        && rm -rf mtx
+    #end if
 
-@CMD@
-
-#if $in.adata_format == 'mtx'
-&& rm -rf mtx
+#else:
+        python '$__tool_directory__/tsv_to_loompy.py'
+        -c '${hd5_format.coldata}'
+        -r '${hd5_format.rowdata}'
+        -f '${hd5_format.mainmatrix}'
+        #if $hd5_format.other_files:
+            '${hd5_format.other_files}'
+        #end if
 #end if
       ]]></command>
     <configfiles>
         <configfile name="script_file"><![CDATA[
 @CMD_imports@
-#if $in.adata_format == 'loom'
+#if $hd5_format.filetype == 'anndata'
+#if $hd5_format.in.adata_format == 'loom'
 adata = ad.read_loom(
-    '$in.input',
-    sparse=$in.sparse,
-    cleanup=$in.cleanup,
-    X_name='$in.x_name',
-    obs_names='$in.obs_names',
-    var_names='$in.var_names')
+    '$hd5_format.in.input',
+    sparse=$hd5_format.in.sparse,
+    cleanup=$hd5_format.in.cleanup,
+    X_name='$hd5_format.in.x_name',
+    obs_names='$hd5_format.in.obs_names',
+    var_names='$hd5_format.in.var_names')
 
-#else if $in.adata_format == 'tabular'
-    #set delimiter=$in.input.metadata.delimiter
+#else if $hd5_format.in.adata_format == 'tabular'
+    #set delimiter=$hd5_format.in.input.metadata.delimiter
     #if $delimiter != ','
         #set delimiter='\\t'
     #end if
 adata = ad.read_csv(
-    '$in.input',
+    '$hd5_format.in.input',
     delimiter='$delimiter',
-    first_column_names=$in.first_column_names)
+    first_column_names=$hd5_format.in.first_column_names)
 
-#else if $in.adata_format == 'mtx'
-    #if $in.tenx.use == 'no'
-adata = ad.read_mtx(filename='$in.matrix')
+#else if $hd5_format.in.adata_format == 'mtx'
+    #if $hd5_format.in.tenx.use == 'no'
+adata = ad.read_mtx(filename='$hd5_format.in.matrix')
     #else
 import scanpy as sc
 adata = sc.read_10x_mtx(
     'mtx',
-    var_names='$in.tenx.var_names',
-    make_unique=$in.tenx.make_unique,
+    var_names='$hd5_format.in.tenx.var_names',
+    make_unique=$hd5_format.in.tenx.make_unique,
     cache=False,
-    gex_only=$in.tenx.gex_only)
+    gex_only=$hd5_format.in.tenx.gex_only)
     #end if
 
-#else if $in.adata_format == 'umi_tools'
-adata = ad.read_umi_tools('${in.input}.gz')
+#else if $hd5_format.in.adata_format == 'umi_tools'
+adata = ad.read_umi_tools('${hd5_format.in.input}.gz')
 
 #end if
-
 adata.write('anndata.h5ad')
+#end if
 ]]></configfile>
     </configfiles>
     <inputs>
-        <conditional name="in">
-            <param name="adata_format" type="select" label="Format for the annotated data matrix">
-                <option value="loom">Loom</option>
-                <option value="tabular">Tabular, CSV, TSV</option>
-                <option value="mtx">Matrix Market (mtx), from Cell ranger or not</option>
-                <option value="umi_tools">UMI tools</option>
+        <conditional name="hd5_format">
+            <param name="filetype" type="select" label="hd5 format to be created">
+                <option value="anndata" selected="true">Anndata file</option>
+                <option value="loom">Loom file</option>
             </param>
-            <when value="loom">
-                <param name="input" type="data" format="loom" label="Annotated data matrix"/>
-                <param name="sparse" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Is the data matrix to read sparse?"/>
-                <param name="cleanup" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Cleanup?"/>
-                <param name="x_name" type="text" value="spliced" label="X_name"/>
-                <param name="obs_names" type="text" value="CellID" label="obs_names"/>
-                <param name="var_names" type="text" value="Gene" label="var_names"/>
-            </when>
-            <when value="tabular">
-                <param name="input" type="data" format="tabular,csv,tsv" label="Annotated data matrix"/>
-                <param name="first_column_names" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Does the first column store the row names?"/>
-            </when>
-            <when value="mtx">
-                <param name="matrix" type="data" format="mtx" label="Matrix"/>
-                <conditional name="tenx">
-                    <param name="use" type="select" label="Use 10x Genomics formatted mtx">
-                        <option value="no">No</option>
-                        <option value="legacy_10x">Output from Cell Ranger v2 or earlier versions</option>
-                        <option value="v3_10x">Output from Cell Ranger v3 or later versions</option>
+            <when value="anndata">
+                <conditional name="in">
+                    <param name="adata_format" type="select" label="Format for the annotated data matrix">
+                        <option value="loom">Loom</option>
+                        <option value="tabular">Tabular, CSV, TSV</option>
+                        <option value="mtx">Matrix Market (mtx), from Cell ranger or not</option>
+                        <option value="umi_tools">UMI tools</option>
                     </param>
-                    <when value="no"/>
-                    <when value="legacy_10x">
-                        <param name="genes" type="data" format="tabular" label="Genes"/>
-                        <expand macro="params_10x"/>
+                    <when value="loom">
+                        <param name="input" type="data" format="loom" label="Annotated data matrix"/>
+                        <param name="sparse" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Is the data matrix to read sparse?"/>
+                        <param name="cleanup" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Cleanup?"/>
+                        <param name="x_name" type="text" value="spliced" label="X_name"/>
+                        <param name="obs_names" type="text" value="CellID" label="obs_names"/>
+                        <param name="var_names" type="text" value="Gene" label="var_names"/>
+                    </when>
+                    <when value="tabular">
+                        <param name="input" type="data" format="tabular,csv,tsv" label="Annotated data matrix"/>
+                        <param name="first_column_names" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Does the first column store the row names?"/>
                     </when>
-                    <when value="v3_10x">
-                        <param name="features" type="data" format="tabular" label="Features"/>
-                        <expand macro="params_10x"/>
+                    <when value="mtx">
+                        <param name="matrix" type="data" format="mtx" label="Matrix"/>
+                        <conditional name="tenx">
+                            <param name="use" type="select" label="Use 10x Genomics formatted mtx">
+                                <option value="no">No</option>
+                                <option value="legacy_10x">Output from Cell Ranger v2 or earlier versions</option>
+                                <option value="v3_10x">Output from Cell Ranger v3 or later versions</option>
+                            </param>
+                            <when value="no"/>
+                            <when value="legacy_10x">
+                                <param name="genes" type="data" format="tabular" label="Genes"/>
+                                <expand macro="params_10x"/>
+                            </when>
+                            <when value="v3_10x">
+                                <param name="features" type="data" format="tabular" label="Features"/>
+                                <expand macro="params_10x"/>
+                            </when>
+                        </conditional>
+                    </when>
+                    <when value="umi_tools">
+                        <param name="input" type="data" format="tabular" label="condensed count matrix from UMI tools"/>
                     </when>
                 </conditional>
             </when>
-            <when value="umi_tools">
-                <param name="input" type="data" format="tabular" label="condensed count matrix from UMI tools"/>
+            <when value="loom">
+                <param name="mainmatrix" type="data" format="tabular" label="File for main layer of loom file." help="All subsequent tsv must be the same dimensions as this file. When converted back to tsv using hd5 export, this will be labeled as 'mainmatrix.tsv'"/>
+                <param name="other_files" type="data" format="tabular" multiple="true" optional="true" label="Add layers" help="Adds layers of same dimension to the loom file. When converted to tsv using hd5 export, these layers will retain their names."/>
+                <param name="coldata" type="data" format="tabular" label="Tsv of column data." help="First row is column attributes, subsequent are values."/>
+                <param name="rowdata" type="data" format="tabular" label="Tsv of row data." help="First row is row attributes, subsequent are values."/>
             </when>
         </conditional>
     </inputs>
     <outputs>
-        <data name="anndata" format="h5ad" from_work_dir="anndata.h5ad" label="${tool.name} on ${on_string}"/>
+        <data name="anndata" format="h5ad" from_work_dir="anndata.h5ad" label="Anndata import on ${on_string}">
+            <filter>hd5_format['filetype'] == 'anndata'</filter>
+        </data>
+        <data name="loomdata" format="loom" from_work_dir="converted.loom" label="Loom import on ${on_string}">
+            <filter>hd5_format['filetype'] == 'loom'</filter>
+        </data>
     </outputs>
     <tests>
-        <test>
+        <test expect_num_outputs="1">
             <conditional name="in">
                 <param name="adata_format" value="loom"/>
                 <param name="input" value="krumsiek11.loom" />
@@ -154,7 +185,7 @@
             </assert_stdout>
             <output name="anndata" value="import.loom.krumsiek11.h5ad" ftype="h5ad" compare="sim_size"/>
         </test>
-        <test>
+        <test expect_num_outputs="1">
             <conditional name="in">
                 <param name="adata_format" value="tabular"/>
                 <param name="input" value="adata.csv"/>
@@ -167,7 +198,7 @@
             </assert_stdout>
             <output name="anndata" value="import.csv.h5ad" ftype="h5ad" compare="sim_size"/>
         </test>
-        <test>
+        <test expect_num_outputs="1">
             <conditional name="in">
                 <param name="adata_format" value="tabular"/>
                 <param name="input" value="adata.tsv"/>
@@ -180,7 +211,7 @@
             </assert_stdout>
             <output name="anndata" value="import.tsv.h5ad" ftype="h5ad" compare="sim_size"/>
         </test>
-        <!--<test>
+        <!--<test expect_num_outputs="1">
             <conditional name="in">
                 <param name="adata_format" value="mtx"/>
                 <param name="matrix" value="matrix_10x_v1.2.0.mtx"/>
@@ -220,23 +251,32 @@
             </conditional>
             <output name="anndata" value="import.mtx.v3_10x.h5ad" ftype="h5ad" compare="sim_size"/>
         </test>!-->
-        <test>
+        <test expect_num_outputs="1">
+            <param name="filetype" value="anndata"/>
             <conditional name="in">
                 <param name="adata_format" value="umi_tools"/>
                 <param name="input" value="umi_tools.tsv"/>
             </conditional>
             <output name="anndata" value="import.umi_tools.h5ad" ftype="h5ad" compare="sim_size"/>
         </test>
+        <test expect_num_outputs="1">
+            <param name="filetype" value="loom"/>
+            <param name="mainmatrix" value="firstlayer.tsv"/>
+            <param name="other_files" value="secondlayer.tsv"/>
+            <param name="coldata" value="cols.tsv"/>
+            <param name="rowdata" value="rows.tsv"/>
+            <output name="loomdata" value="converted.loom.test" ftype="loom" compare="sim_size"/>
+        </test>
     </tests>
     <help><![CDATA[
 **What it does**
 
-This tool creates an AnnData dataset from several input types:
+This tool creates an AnnData or loom dataset from several input types:
 
-- Loom (`read_loom method <https://anndata.readthedocs.io/en/latest/anndata.read_loom.html>`__) 
-- Tabular (`read_csv method <https://anndata.readthedocs.io/en/latest/anndata.read_csv.html>`__) 
-- Matrix Market (mtx), from Cell ranger or not (`read_mtx method <https://anndata.readthedocs.io/en/latest/anndata.read_mtx.html>`__) 
-- UMI tools (`read_umi_tools method <https://anndata.readthedocs.io/en/latest/anndata.read_umi_tools.html>`__) 
+- Loom (`read_loom method <https://anndata.readthedocs.io/en/latest/anndata.read_loom.html>`__)
+- Tabular (`read_csv method <https://anndata.readthedocs.io/en/latest/anndata.read_csv.html>`__)
+- Matrix Market (mtx), from Cell ranger or not (`read_mtx method <https://anndata.readthedocs.io/en/latest/anndata.read_mtx.html>`__)
+- UMI tools (`read_umi_tools method <https://anndata.readthedocs.io/en/latest/anndata.read_umi_tools.html>`__)
 
 @HELP@
     ]]></help>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loompy_to_tsv.py	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+
+"""Converts a loompy file to tsv file(s). Each layer becomes a new file."""
+
+import argparse
+
+import loompy
+
+parser = argparse.ArgumentParser(description="Loompy file converter flags")
+parser.add_argument('--version', action='version', version='%(prog)s 0.1.0',
+                    help="Displays tool version")
+parser.add_argument("-f", "--file", help="loom file to import")
+args = parser.parse_args()
+
+file = args.file
+
+matrices = []
+allcols = []
+colstrings = []
+allrows = []
+
+# Build background info for all attributes and layers
+loompyfile = loompy.connect(file)
+row_attributes = loompyfile.ra.keys()  # List of row attributes
+for row in row_attributes:  # Each list represents rownames for row_attributes
+    c_row = loompyfile.ra[row]
+    c_row = [str(r) for r in c_row]
+    allrows.append(c_row)
+col_attributes = loompyfile.ca.keys()  # List of column attributes
+for col in col_attributes:  # each list represents colnames for col_attributes
+    c_col = loompyfile.ca[col]
+    c_col = [str(c) for c in c_col]
+    allcols.append(c_col)
+layers = loompyfile.layers.keys()  # List of layers
+for layer in layers:  # List with each element being a loompy layer
+    c_layer = loompyfile[layer]
+    c_layer = c_layer[:, :]
+    c_layer = c_layer.astype(str)
+    matrices.append(c_layer)
+
+# Create column attribute output
+with open("attributes/col_attr.tsv", "w") as colout:
+    col_attributes = "\t".join(col_attributes) + "\n"
+    colout.write(col_attributes)
+    for length in range(0, len(c_col)):
+        attributestring = ""
+        for col in allcols:
+            attributestring = attributestring + col[length] + "\t"
+        while attributestring[-1] == "\t":
+            attributestring = attributestring[:-1]
+        colout.write(attributestring)
+        colout.write("\n")
+# Create row attribute output
+with open("attributes/row_attr.tsv", "w") as rowout:
+    row_attributes = "\t".join(row_attributes) + "\n"
+    rowout.write(row_attributes)
+    for length in range(0, len(c_row)):
+        attributestring = ""
+        for row in allrows:
+            attributestring = attributestring + row[length] + "\t"
+        while attributestring[-1] == "\t":
+            attributestring = attributestring[:-1]
+        rowout.write(attributestring)
+        rowout.write("\n")
+
+# Build output files for each layer
+for x in range(0, len(layers)):
+    # Output file name generation
+    if layers[x] in layers[0: x]:  # Different output names if layers have same names somehow
+        repeats = layers[0, x].count(layer[x])
+        outputname = "output/" + layers[x] + repeats + ".tsv"
+    elif layers[x] == "":  # Empty layer name
+        outputname = "output/mainmatrix.tsv"
+    else:
+        outputname = "output/" + str(layers[x]) + ".tsv"  # Usual case
+# Matrix output
+    with open(outputname, "w") as outputmatrix:
+        for line in matrices[x]:
+            line = "\t".join(line)
+            line += "\n"
+            line = line
+            outputmatrix.write(line)
--- a/macros.xml	Thu Dec 12 09:23:27 2019 -0500
+++ b/macros.xml	Mon Jan 06 13:45:13 2020 -0500
@@ -15,13 +15,19 @@
         </citations>
     </xml>
     <xml name="version_command">
-        <version_command><![CDATA[python -c "import anndata as ad;print('anndata version: %s' % ad.__version__)"]]></version_command>
+        <version_command><![CDATA[python -c "import anndata as ad;print('anndata version: %s' % ad.__version__); import loompy;print('\nloompy version: %s' % loompy.__version__)"]]></version_command>
     </xml>
     <token name="@CMD@"><![CDATA[
 cat '$script_file' &&
 python '$script_file'
     ]]>
     </token>
+    <token name="@LOOMCMD@"><![CDATA[
+mkdir ./output &&
+mkdir ./attributes &&
+python '$__tool_directory__/loompy_to_tsv.py' -f '${hd5_format.input}'
+    ]]>
+    </token>
     <token name="@CMD_imports@"><![CDATA[
 import anndata as ad
     ]]>
@@ -33,15 +39,27 @@
 
 AnnData stores a data matrix `X` together with annotations of observations `obs`, variables `var` and unstructured annotations `uns`.
 
-.. image:: https://falexwolf.de/img/scanpy/anndata.svg 
+.. image:: https://falexwolf.de/img/scanpy/anndata.svg
 
 
-AnnData stores observations (samples) of variables (features) in the rows of a matrix. This is the convention of the modern classics 
-of statistics (`Hastie et al., 2009 <https://web.stanford.edu/~hastie/ElemStatLearn/>`__)  and machine learning (Murphy, 2012), the convention of dataframes both in R and Python and the established statistics 
+AnnData stores observations (samples) of variables (features) in the rows of a matrix. This is the convention of the modern classics
+of statistics (`Hastie et al., 2009 <https://web.stanford.edu/~hastie/ElemStatLearn/>`__)  and machine learning (Murphy, 2012), the convention of dataframes both in R and Python and the established statistics
 and machine learning packages in Python (statsmodels, scikit-learn).
 
 More details on the `AnnData documentation
 <https://anndata.readthedocs.io/en/latest/anndata.AnnData.html>`__
+
+
+**Loom data**
+
+Loom files are an efficient file format for very large omics datasets, consisting of a main matrix, optional additional layers, a variable number of row and column annotations, and sparse graph objects.
+
+.. image:: https://linnarssonlab.org/loompy/_images/Loom_components.png
+
+
+Loom files to store single-cell gene expression data: the main matrix contains the actual expression values (one column per cell, one row per gene); row and column annotations contain metadata for genes
+and cells, such as Name, Chromosome, Position (for genes), and Strain, Sex, Age (for cells).
+
     ]]>
     </token>
     <xml name="params_chunk_X">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modify_loom.py	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+"""This program adds layers, row attributes or column attributes for loom files"""
+
+import argparse
+
+import loompy
+import numpy as np
+
+parser = argparse.ArgumentParser(description="Loompy file converter flags")
+parser.add_argument('--VERSION', action='version', version='%(prog)s 0.1.0',
+                    help="Displays tool version")
+parser.add_argument('--file', '-f',
+                    help="Loom file to which data will be added")
+parser.add_argument('--rowfile', '-r', help="File of row attributes & values")
+parser.add_argument('--colfile', '-c',
+                    help="File of column attributes and values")
+parser.add_argument('--layers', '-l', nargs='*',
+                    help="Input tsv files. First file becomes main layer.")
+parser.add_argument('--add', '-a', choices=["rows", "cols", "layers"],
+                    help="Selects rows, columns or layers to be added to file")
+args = parser.parse_args()
+
+lfile = args.file
+if args.rowfile:
+    rowfile = args.rowfile
+if args.colfile:
+    colfile = args.colfile
+if args.layers:
+    alllayers = args.layers
+addselect = args.add
+# Check proper flags for chosen attributes are being added
+if addselect == "cols" and not args.colfile:
+    raise Exception("To add column attributes, column flag and file must be provided")
+if addselect == "rows" and not args.rowfile:
+    raise Exception("To add row attributes, row flag and file must be provided")
+if addselect == "layers" and not args.layers:
+    raise Exception("To add layers, a layer flag and file(s) must be provided")
+
+layernames = []
+rowdict = {}
+coldict = {}
+
+with loompy.connect(lfile) as loomfile:
+    # Loom file dimensions
+    nrow = loomfile.shape[0]
+    ncol = loomfile.shape[1]
+    if addselect == "layers":
+        layernames = []
+        # Generate layer names based on file names
+        for x in range(0, len(alllayers)):
+            layer = alllayers[x]
+            layer = layer.split("/")[-1].split(".")[-2]  # Takes away path, takes off extension
+            layernames.append(layer)
+        # Add in the layers themselves
+        for layer in range(0, len(alllayers)):
+            matrix = ""
+            with open(alllayers[layer], "r") as infile:
+                rows = 0
+                count = 0
+                for line in infile:
+                    if count == 0:
+                        cols = len(line.split("\t"))
+                        if cols != ncol:
+                            raise Exception("Dimensions of new matrix incorrect for this loom file. New matrices must be %d by %d" % (nrow, ncol))
+                    matrix = matrix + line + "\t"
+                    rows += 1
+                if rows != nrow:
+                    raise Exception("Dimensions of new matrix incorrect for this loom file. New matrices must be %d by %d")
+            matrix = matrix.split("\t")
+            matrix = [float(n) for n in matrix[:-1]]
+            matrix = np.asarray(matrix).reshape(nrow, ncol)
+            loomfile[layernames[layer]] = matrix
+    elif addselect == "rows":
+        with open(rowfile, "r") as rows:
+            count = 0
+            for line in rows:
+                line = line.strip().split("\t")
+                if count == 0:  # First time through
+                    row_attributes = line
+                    for x in row_attributes:
+                        rowdict[x] = []
+                    count += 1
+                else:
+                    for x in range(0, len(line)):
+                        rowdict[row_attributes[x]].append(line[x])
+        for x in row_attributes:
+            if len(rowdict[x]) != nrow:
+                raise Exception("Incorrect length of row. Row length must be: %d" % nrow)
+            loomfile.ra[x] = rowdict[x]
+    elif addselect == "cols":
+        with open(colfile, "r") as cols:
+            count = 0
+            for line in cols:
+                line = line.replace('\"', "")
+                line = line.replace(' ', "")
+                line = line.strip().split("\t")
+                if count == 0:  # First time through
+                    col_attributes = line
+                    for x in col_attributes:
+                        coldict[x] = []
+                    count += 1
+                else:
+                    for x in range(0, len(line)):
+                        coldict[col_attributes[x]].append(line[x])
+        for y in col_attributes:
+            if len(coldict[y]) != ncol:
+                raise Exception("Incorrect length of column. Column length must be: %d" % ncol)
+            loomfile.ca[y] = coldict[y]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/addlayer1.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,9 @@
+-4.38397705861083	14.292813312163	-3.50113245239144	0.822254333007829	1.00150289648448	2.43591204698924	-0.356677013622828	-6.11947364969354	2.56281003005924	6.63909009032078	-0.78946499862756	4.69845868698249	0.555316773542253	1.14493347970535	-2.13170480396421	0.671242754395511	-1.24598424970653	2.35762885939	0.808249063291586	2.13338650412044	-0.442400711567299	0.185262494040311	2.11898976841304	1.33325569029047	-1.59297725345935	-0.966752781646448	3.58792591654639	1.66406580309397	0.63327385793388	-0.308925411126234	1.62030751470511	-0.551680746030133	0.481109445913889	-1.29522624182828	-1.2921145302749	1.35092954319461	0.357971803776218	0.602387478388324	-0.86450428384588	-0.253516849675122	-0.191991523300002	-1.23045693386899	1.10601149579208	0.474927307151347	0.0295127518668576	0.347320109574423	-0.124263697792595	-1.1355438083115	-0.408955132576027	0.652951279673313	-0.560853895759609	-1.50956633618222	-0.372228084801999	0.649248591501578	1.24501120925882	-0.333165552309464	-0.632289365875825	-0.489136074968853	0.606241184362324	-0.0697756202083343	0.723366081694609	0.269156075893411	-1.1927509857456	1.82685437466378	0.112075843817834	-0.393322613665142	1.28166028199521	-1.44150233543534	0.439168555592787	0.344017904319427	1.81395743926678	0.508805925557063	0.848238740356503	1.11258006953971	-0.54997200023266	0.809927913686388	-0.738427841761447	-0.453122730649697	-0.486373667035062	0.746360065063862	0.700920021470684	-0.313589192332652	-0.906138725835488	-0.661793483747946	-0.271124869295733	-0.00930238204411152	0.3215219758547	-1.25380192942129	-1.55728763598058	0.0952110940501214	0.00839453406532392	-0.0541448293428013	0.18477775291979	-0.62373646202135	-0.0772377796590389	-0.662366716574923	-1.03592409403641	-0.89249106169138	-0.717710251591651	0.776880357163071
+9.30281248024864	11.5335015413635	2.30875450845203	-1.38857898424223	1.03817215518254	3.6567570331059	10.4188385719381	-16.3128929934454	-3.60726875451658	13.7068591589974	1.33467070509089	5.38122487635218	0.0543994941205517	-2.70133427961325	0.0833615201988052	0.536168996886923	-0.0760546449729948	-0.78214225809622	-1.95248285633292	-0.326587425115489	-1.35500688419885	2.95434733271686	0.505653381720533	-0.295669096974786	2.26651004107081	3.53486650501347	3.220565758935	6.7321178798513	1.94091616482302	-1.69913768324206	-4.05100974370053	-1.27783882963281	-1.01355047824763	3.74963974715759	-2.58850482422048	6.8833099016512	0.662009356554069	3.44073177658161	-0.418512226093587	4.47846431563314	-1.74206293554388	1.84260608944111	-4.30015045993517	0.685087251537494	3.24882497326721	1.8095695466243	0.867087349923969	-3.63680218472816	4.1068657392081	-1.47022937993631	-5.04481250049395	1.16372912821134	-0.673610496402694	-0.480268341823079	-1.75373530199601	0.89984292745755	-0.685746934741278	1.35462132079302	-2.52570708801692	-2.74016842015935	-0.393885487708287	1.35180900874174	0.566787604497255	3.47016490744519	1.19410589958458	0.0954571935227406	0.465830133214735	0.969800327817249	-2.30608823177911	-1.36361346526534	-1.07384772734754	-1.28884764388441	-1.1808330583485	-2.23980854377317	-1.85162318607013	-0.069323155428631	-0.398294053191192	0.533970283418857	0.996857378845262	0.0816831777715224	0.444550338509664	-2.91836706827678	-0.267414770797715	-0.892474756707529	2.17409610136124	1.74372514825455	1.50066087410441	2.38996632942927	0.0469000573619218	-0.664299183380684	2.60790199917983	-2.40710478607531	1.24547812809717	2.41674046127559	-1.46444549406779	0.364174652919165	1.30109643082257	-0.577449382132677	-1.86505783133924	-1.99746975425092
+-5.89727512326108	-1.77246933119333	1.52782219208749	2.53511205650502	-2.53100068245452	-0.024300692685485	1.54330662794615	-2.74799503275627	-3.35444290166925	4.19511229947865	0.465153187650876	1.75331948382231	-1.16526308150911	-0.0943840089716619	-0.24095624876061	1.66521052849681	-2.11688113706039	-0.812191599443991	1.84008723741373	1.09605489701982	0.353335700092688	-0.523288451494122	-0.299012962148017	-2.88920874353573	-0.513481504763197	-2.21470284158116	0.416199869738419	-1.71617700908213	0.13685968824668	-0.489715075784864	-0.0102036078613937	-0.516945547789662	0.352617930831872	-0.172077340456524	0.196453120465679	1.22308205746272	-1.4849640784569	-0.243377392627181	0.463503859887059	1.04264188740704	-0.331273064367236	-1.0125587303605	-0.680700905917006	-0.511146692498302	0.140274079827094	1.22492893349224	0.855720140552588	0.382720446624883	-1.30875493636543	-0.500274960509595	0.700372605279355	-0.812474995526137	0.149519909761233	0.533411145285562	1.67008404672273	0.928331439602055	1.02096341369662	-0.261832925209925	0.629853148817829	1.7219125379708	1.00569983479743	-0.00450402234155931	-0.341416796091634	-1.3872557790274	1.80055359739341	-0.495374006741585	1.89145980335166	-0.693472867202045	-1.50974963506413	-1.2209076341959	-0.42594436412776	0.632021725852767	1.94342611009792	-0.540923793215291	0.201663676681874	0.163531142284654	0.997291087405646	0.869073146379135	-0.143753031104283	0.675612490310951	1.42469798361898	-0.756276309215264	-0.654925014119027	-0.949160720897864	-1.64701975142294	-1.10655034901924	1.29407378748758	1.15840377994492	1.8067185575117	-0.835226683327202	1.5648561397647	0.204808545499026	1.84035824825071	-0.981778359868067	-0.0289116785905805	1.23206606204954	-0.546713726320213	-0.629137661987508	-0.69213855880832	0.896728867097452
+-5.29270675301426	9.90705208795245	-5.64389382322256	-0.23270936454856	-8.00668157348614	-3.7826928671003	8.18196260183207	-5.73131556261441	9.61491655549755	1.65872404583472	0.6931540256981	-0.375292304271315	2.50804219920716	-1.86911671797384	-0.932517291897027	1.77919191661771	2.80170359222648	0.738113125484133	0.708504101366545	1.22066296829662	2.10045001006274	0.182322661637994	1.67434719528026	0.935397923906938	-2.561768409605	0.581039221769399	-0.407966302556971	-0.939901920959218	-0.590698586514989	-0.718006228836953	0.0996258132335209	-1.07932947402778	0.13450499684297	0.945797885637747	0.166188540192427	1.60684758988644	0.604234735179785	-0.463220916481101	0.231103189936207	0.119622602387229	0.71354769917271	1.65722623058665	-0.741448027546473	0.259192208047517	0.8291468631134	-0.117263739306486	-0.147582941706287	0.615321152218305	-0.551001006157352	0.621370181538221	0.311858058587134	2.65627826972861	-0.409401739107173	-0.889254236720799	-0.316240220054344	1.65029514443773	-0.329299152922808	1.1443748905888	1.09697477595742	1.0950696352531	0.517103431102195	-0.57854363786886	-1.05143518912101	-0.597195894417476	-1.52272606255708	-1.45996052619658	-0.16369116403685	1.25171548375323	1.32264262600894	-0.156879567237048	0.10642556389866	0.198583595909365	-0.612200116456148	0.850003590942363	-0.362186192823249	0.434242782164353	0.025143942334855	-1.43084257833896	0.349051292219086	-1.10071268661716	-0.663298490158815	1.68031258466557	-0.763051031379906	-0.600493768630168	-1.18545167697973	1.57551925143202	-1.30181346792223	0.728548494165308	2.34566406049576	-0.1884974788404	0.0118345339438655	-1.92948304988134	-1.27153538096398	-1.58327361831734	-0.260849294996154	1.03685648548191	-0.0437721407831781	1.00014006822958	-0.938662826224149	-0.681755709297571
+-6.08405321020853	-7.4364434223963	-0.373159059998994	1.85654867754332	-0.066646375393358	-0.812924879075801	3.77256207671638	-4.45857785752643	-1.17510687896568	5.36398845214791	-0.0444852947462604	1.68800891479541	-1.02343129106454	-0.0291781173718133	0.43336514102907	0.990488346010292	-0.390089117586027	-0.457623162821967	-0.226781546433054	-0.555218647277086	0.546384482359304	0.42572738657391	-0.446772412376349	0.398548443431641	1.20781385870181	1.51524917822676	-0.725894206140178	1.18804156528341	-0.291832474002874	-0.27334865010719	0.724820114357118	-0.754521181462694	-0.219142473146785	-0.547687176358784	0.224136403157904	1.34562257942705	0.0199235207085279	0.69339897171333	0.455378706946114	0.570216029696232	-0.743264335483396	0.430965842886427	0.956994648442376	-0.149622852814064	0.422662124186914	-0.667500360398019	0.126155771988897	0.189734014278429	-0.495090800986108	1.45314992106433	0.279597362279374	0.00420831221791874	0.0684328927904376	0.564534608052136	0.180566928063181	-0.212532593283124	0.165962191853296	-0.737236941067074	1.00374592433454	-0.489192171197334	0.0539789704682752	-0.0245445454807236	-0.810706903383208	0.397757427163805	-0.834737274946879	1.31784747773081	-0.863296976786124	0.791009220921894	-0.115535163453668	0.239851976966603	0.822806870619781	1.46817239457077	-0.0124083750837263	0.421701646259027	0.606800925633079	-0.615348044902974	0.00771763746167571	-1.28413167291888	1.25188349695723	-1.2725572369587	0.666176677913971	0.270927203640637	0.214522143842674	0.462719837122182	-0.177097322640291	0.0588285152479112	-1.35804255884329	0.693252357054687	0.632882198947294	-1.16659093085466	-0.00943380228354805	0.152370596963306	-0.0930460025434874	0.371587071821932	0.398461629580755	2.0789838212624	0.239120325286236	-0.697665704632893	-1.04006734705331	-1.1903200870504
+-4.35898581592111	10.8295807087292	-9.33885578536902	-3.88278806546879	2.57336996898482	-0.787128307301999	4.49394697617967	0.987317973527029	-0.225552365005083	4.79243994675665	0.307132342851648	-0.00145140061122141	-1.85227464816376	-0.0146708390591366	1.58989123998554	-0.9849461656821	0.63142833831129	0.387885029309716	1.52980092070315	-3.23439503156197	3.32085985699086	-0.0421136588930143	-0.283455894117478	-2.34109197749086	-0.424720533947467	-1.02447961214719	1.1122173946011	-1.01924324644954	0.80461628206255	0.232354115524204	0.752233505845615	1.1628978386598	0.301075834919574	-0.694363806595065	-0.899225283748419	0.543510566685045	0.893707801826774	-0.944916816404443	-1.36393372385435	1.65431576964293	0.746573599498895	-0.102838075889582	-0.5515109990147	-1.54827280151299	-0.445191727598828	-0.486932562166509	0.616319749247666	-0.0302575922813826	-1.02185774427578	-0.736444939587494	0.46764320276055	1.0904994570631	0.748029573521368	1.24714317270018	-0.650648493309113	1.18928361183252	-2.60324984503231	0.633787352775379	1.41517229407607	-0.159125715586533	1.0219321983147	-0.831168755689713	1.30942153193657	0.0753733563214212	0.285734058354515	-0.844644707777072	-0.236157958311837	0.20122330702161	1.01999662814264	1.86348523432828	0.216795698696114	-1.32687878081284	-0.392155900831159	1.03431815144232	0.124669010882415	0.474592236603064	0.542919054766528	-1.88877707853684	-1.65148897922194	2.40220393457081	0.548940519345852	-0.256496494870999	0.191515904091741	2.15710802253758	-0.205817145081161	1.05839422546064	1.68258415026592	-0.0918278059169231	1.90068387612529	-0.817314890418665	0.715322848822701	-2.51914068778904	-0.695236426531822	1.05884466477253	0.6475293063184	-0.167640902530503	0.0931156641327686	-1.37860166201551	-1.4994346966975	-1.17559042360564
+-5.44956627518923	0.200884241359212	-0.0940099392362255	0.391424565921512	-4.42294103296365	2.02612071023864	-1.9620071791874	-4.26175597130446	0.8998793535643	3.76053900904884	-1.6361298996455	2.36042379179368	-2.75819699300257	-0.100530502966349	-0.0427288135063918	0.0640031148216666	0.523327742271745	0.160640450650541	-1.0380547955777	0.550687662279054	-0.527266599351878	1.3816058202807	-2.69254136642811	-0.611084358977462	-0.935089408016054	-0.0387188817465848	0.793995944833708	-1.12785316556236	0.445937400816127	-0.946557945637926	1.18257558164449	-1.34233534254901	0.0176311421070648	-0.224900754574182	-0.204023222723773	1.51743434767516	-0.499316194896609	-0.116333597690277	1.02079557154874	1.6780373761605	0.171333151844323	-1.34382266831776	0.00270449514108322	1.29347313329421	0.896723180471322	-0.634461498200752	-0.213229675671139	0.785371380619926	-1.73220953509193	-1.53657066969688	-0.355849318354773	-1.24074606851403	0.136828779405145	0.97972003690276	0.0368991085138718	0.759313802193281	-0.0299124672475207	-0.0126005138019731	1.86019501588837	-0.0193050844578417	-0.370387588851618	-0.335589748476321	1.51063959473573	-0.32446285310899	-0.0420484344751731	1.03468246820123	1.15195012057021	-0.7585649009828	0.0340758533177857	-1.76245837695789	1.1953234508049	0.148246471218968	-0.465408959424267	-1.93276565033051	-0.601507670674328	0.561693178023859	-0.344148325356987	-1.76155715131425	1.53586806269923	-0.973497071015107	-0.0154265589569301	0.389711467291695	-0.239877266341895	0.352795111764336	-0.190135198230446	-0.208684600336429	2.07918244700086	-0.361025972011884	1.63078492845337	0.488804843489253	-0.682220518809875	-0.29463668542297	0.311427730874536	0.503090238195356	-0.373064491000882	0.23417554807577	-1.48465915072341	-1.46085021332334	-0.495461794448377	-0.17775442234612
+-3.97575208570735	11.0544858387352	7.6173060428113	6.63048929774542	-5.30994749122935	1.88722422257416	4.09251614216244	1.44648639362641	-7.25006907798796	6.86869361179653	0.491494050662433	-2.25651388279331	9.5161454340774	1.01476184398758	2.5399705796852	-2.21669881532076	3.98394683759498	3.59383510388346	6.12746355517479	-0.715726354893143	3.55159403974729	-1.11574398116924	-0.525929195057429	0.878154489745832	-0.230493171744922	0.714464510169232	-0.157245107145587	-3.4342599800683	0.48505980459346	0.702993897575898	-0.135378631070949	2.07954004197705	-0.690953937097613	1.27624456885549	1.21947693928713	1.65808520486344	0.961593556571414	-0.311912078906821	-0.188898767072046	-0.840060825549656	-1.12921186104506	1.56017494876464	0.411131589159066	-0.0521633935484305	-1.69684514175225	-0.0333681471142678	-0.13906225301883	1.24899138448782	-0.313535620881124	-0.310399053687893	0.998855535319549	-0.491386912744097	-2.65588822465539	-0.262301430974959	-0.37741200187771	-0.41429490709306	-0.561255237373123	-1.15276356159977	2.78298825141619	-0.502905861300848	-0.675640036112791	0.861407188085173	0.670870463440124	1.79627949867291	-1.49071314746396	1.10513353172237	0.892902985092724	-0.050023000293664	-2.0951156395428	-1.56875762272546	0.361989901125448	-0.225302477699307	0.169862551615696	-0.49530667266779	0.458175186664475	-1.32231097560469	0.786081372282524	-0.0484494603142322	0.706878176692001	1.15487020448148	0.531640766037383	-0.138810686002109	0.591943064902141	1.1023101065439	1.76277780537503	-0.905355575172113	0.134769770511889	-0.497015408904865	-0.742656863985804	-0.067343788917104	-0.540927632084057	-0.0580727941856462	-1.0462842718808	-0.00500540976328367	-0.824608358220491	-1.44352688132908	1.75740458742792	-0.44311879378313	-0.662584623920899	0.888462747166643
+-5.277006254183	2.42397087953038	-0.943798001822603	2.85780940799815	2.36895039654097	-2.69659967635116	1.54629605482182	-8.96928156931566	-1.64262157483957	1.43852747962271	-0.967981915016056	-0.390735428021631	-2.15024133526923	0.277271702300901	1.8053039804015	-0.535107559431625	1.67768924818208	-0.421010853147353	-1.16464550016846	-0.0251453460136133	0.436658055348297	-0.29540721194163	0.333748713475055	-0.723208532365344	0.471110811941787	0.726089991234918	-0.157382569241171	-0.379234094421878	0.748812558274635	-0.41301464848253	0.566057622213117	-1.64460356067673	0.891204658261791	-0.34932773880327	-1.30922369726531	-0.173573387498366	0.8056807178332	0.208881576008633	-1.60357889692679	0.908540313457729	-0.292428392920166	-0.0118489017469322	-0.891712950604345	1.16207204758746	0.430624050805364	-0.410051657015908	0.730349459202633	-0.331488261254584	-1.11548393909722	0.956994457204229	-0.175931934021692	-1.2036342551925	-0.231987307226876	0.750428558384009	1.32527020615915	-0.0420682884240139	-0.092958898049259	-0.0122267448532016	0.726126639304472	-0.694555932842187	-0.262226740797341	-1.0291540856062	0.0793211050194524	-0.670890710123743	2.29978649016219	-1.04786389277271	0.0673332449001132	-0.0371298860750165	-0.190086855611152	0.569211538833251	0.919033137444811	0.0635277673597158	1.00004676925338	0.463824012820739	-0.661533287421813	-0.532636001812366	0.13594592076042	0.353092106176299	0.362734586198694	0.648858597916376	-0.947487352382305	-0.890204579930725	-0.481659475836321	-0.382386249884642	-0.565389965376474	0.69470847650723	0.565209012057139	-0.594122862421382	0.374110007433118	0.906000246931211	1.14643222017558	-0.864426844788516	-0.107902667694253	-1.33878812133165	-0.648727117620733	-0.682898186419176	0.152703116395545	1.18647033835958	-0.730347642632863	0.355381103259185
Binary file test-data/addloomout1.loom has changed
Binary file test-data/addloomout2.loom has changed
Binary file test-data/addloomout3.loom has changed
Binary file test-data/addtest.loom has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cols.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,101 @@
+Testing	testing	testing2
+PC1	0	200
+PC2	1	201
+PC3	2	202
+PC4	3	203
+PC5	4	204
+PC6	5	205
+PC7	6	206
+PC8	7	207
+PC9	8	208
+PC10	9	209
+PC11	10	210
+PC12	11	211
+PC13	12	212
+PC14	13	213
+PC15	14	214
+PC16	15	215
+PC17	16	216
+PC18	17	217
+PC19	18	218
+PC20	19	219
+PC21	20	220
+PC22	21	221
+PC23	22	222
+PC24	23	223
+PC25	24	224
+PC26	25	225
+PC27	26	226
+PC28	27	227
+PC29	28	228
+PC30	29	229
+PC31	30	230
+PC32	31	231
+PC33	32	232
+PC34	33	233
+PC35	34	234
+PC36	35	235
+PC37	36	236
+PC38	37	237
+PC39	38	238
+PC40	39	239
+PC41	40	240
+PC42	41	241
+PC43	42	242
+PC44	43	243
+PC45	44	244
+PC46	45	245
+PC47	46	246
+PC48	47	247
+PC49	48	248
+PC50	49	249
+PC51	50	250
+PC52	51	251
+PC53	52	252
+PC54	53	253
+PC55	54	254
+PC56	55	255
+PC57	56	256
+PC58	57	257
+PC59	58	258
+PC60	59	259
+PC61	60	260
+PC62	61	261
+PC63	62	262
+PC64	63	263
+PC65	64	264
+PC66	65	265
+PC67	66	266
+PC68	67	267
+PC69	68	268
+PC70	69	269
+PC71	70	270
+PC72	71	271
+PC73	72	272
+PC74	73	273
+PC75	74	274
+PC76	75	275
+PC77	76	276
+PC78	77	277
+PC79	78	278
+PC80	79	279
+PC81	80	280
+PC82	81	281
+PC83	82	282
+PC84	83	283
+PC85	84	284
+PC86	85	285
+PC87	86	286
+PC88	87	287
+PC89	88	288
+PC90	89	289
+PC91	90	290
+PC92	91	291
+PC93	92	292
+PC94	93	293
+PC95	94	294
+PC96	95	295
+PC97	96	296
+PC98	97	297
+PC99	98	298
+PC100	99	299
Binary file test-data/converted.loom.test has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/finallayer.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,9 @@
+900.0	901.0	902.0	903.0	904.0	905.0	906.0	907.0	908.0	909.0	910.0	911.0	912.0	913.0	914.0	915.0	916.0	917.0	918.0	919.0	920.0	921.0	922.0	923.0	924.0	925.0	926.0	927.0	928.0	929.0	930.0	931.0	932.0	933.0	934.0	935.0	936.0	937.0	938.0	939.0	940.0	941.0	942.0	943.0	944.0	945.0	946.0	947.0	948.0	949.0	950.0	951.0	952.0	953.0	954.0	955.0	956.0	957.0	958.0	959.0	960.0	961.0	962.0	963.0	964.0	965.0	966.0	967.0	968.0	969.0	970.0	971.0	972.0	973.0	974.0	975.0	976.0	977.0	978.0	979.0	980.0	981.0	982.0	983.0	984.0	985.0	986.0	987.0	988.0	989.0	990.0	991.0	992.0	993.0	994.0	995.0	996.0	997.0	998.0	999.0
+1000.0	1001.0	1002.0	1003.0	1004.0	1005.0	1006.0	1007.0	1008.0	1009.0	1010.0	1011.0	1012.0	1013.0	1014.0	1015.0	1016.0	1017.0	1018.0	1019.0	1020.0	1021.0	1022.0	1023.0	1024.0	1025.0	1026.0	1027.0	1028.0	1029.0	1030.0	1031.0	1032.0	1033.0	1034.0	1035.0	1036.0	1037.0	1038.0	1039.0	1040.0	1041.0	1042.0	1043.0	1044.0	1045.0	1046.0	1047.0	1048.0	1049.0	1050.0	1051.0	1052.0	1053.0	1054.0	1055.0	1056.0	1057.0	1058.0	1059.0	1060.0	1061.0	1062.0	1063.0	1064.0	1065.0	1066.0	1067.0	1068.0	1069.0	1070.0	1071.0	1072.0	1073.0	1074.0	1075.0	1076.0	1077.0	1078.0	1079.0	1080.0	1081.0	1082.0	1083.0	1084.0	1085.0	1086.0	1087.0	1088.0	1089.0	1090.0	1091.0	1092.0	1093.0	1094.0	1095.0	1096.0	1097.0	1098.0	1099.0
+1100.0	1101.0	1102.0	1103.0	1104.0	1105.0	1106.0	1107.0	1108.0	1109.0	1110.0	1111.0	1112.0	1113.0	1114.0	1115.0	1116.0	1117.0	1118.0	1119.0	1120.0	1121.0	1122.0	1123.0	1124.0	1125.0	1126.0	1127.0	1128.0	1129.0	1130.0	1131.0	1132.0	1133.0	1134.0	1135.0	1136.0	1137.0	1138.0	1139.0	1140.0	1141.0	1142.0	1143.0	1144.0	1145.0	1146.0	1147.0	1148.0	1149.0	1150.0	1151.0	1152.0	1153.0	1154.0	1155.0	1156.0	1157.0	1158.0	1159.0	1160.0	1161.0	1162.0	1163.0	1164.0	1165.0	1166.0	1167.0	1168.0	1169.0	1170.0	1171.0	1172.0	1173.0	1174.0	1175.0	1176.0	1177.0	1178.0	1179.0	1180.0	1181.0	1182.0	1183.0	1184.0	1185.0	1186.0	1187.0	1188.0	1189.0	1190.0	1191.0	1192.0	1193.0	1194.0	1195.0	1196.0	1197.0	1198.0	1199.0
+1200.0	1201.0	1202.0	1203.0	1204.0	1205.0	1206.0	1207.0	1208.0	1209.0	1210.0	1211.0	1212.0	1213.0	1214.0	1215.0	1216.0	1217.0	1218.0	1219.0	1220.0	1221.0	1222.0	1223.0	1224.0	1225.0	1226.0	1227.0	1228.0	1229.0	1230.0	1231.0	1232.0	1233.0	1234.0	1235.0	1236.0	1237.0	1238.0	1239.0	1240.0	1241.0	1242.0	1243.0	1244.0	1245.0	1246.0	1247.0	1248.0	1249.0	1250.0	1251.0	1252.0	1253.0	1254.0	1255.0	1256.0	1257.0	1258.0	1259.0	1260.0	1261.0	1262.0	1263.0	1264.0	1265.0	1266.0	1267.0	1268.0	1269.0	1270.0	1271.0	1272.0	1273.0	1274.0	1275.0	1276.0	1277.0	1278.0	1279.0	1280.0	1281.0	1282.0	1283.0	1284.0	1285.0	1286.0	1287.0	1288.0	1289.0	1290.0	1291.0	1292.0	1293.0	1294.0	1295.0	1296.0	1297.0	1298.0	1299.0
+1300.0	1301.0	1302.0	1303.0	1304.0	1305.0	1306.0	1307.0	1308.0	1309.0	1310.0	1311.0	1312.0	1313.0	1314.0	1315.0	1316.0	1317.0	1318.0	1319.0	1320.0	1321.0	1322.0	1323.0	1324.0	1325.0	1326.0	1327.0	1328.0	1329.0	1330.0	1331.0	1332.0	1333.0	1334.0	1335.0	1336.0	1337.0	1338.0	1339.0	1340.0	1341.0	1342.0	1343.0	1344.0	1345.0	1346.0	1347.0	1348.0	1349.0	1350.0	1351.0	1352.0	1353.0	1354.0	1355.0	1356.0	1357.0	1358.0	1359.0	1360.0	1361.0	1362.0	1363.0	1364.0	1365.0	1366.0	1367.0	1368.0	1369.0	1370.0	1371.0	1372.0	1373.0	1374.0	1375.0	1376.0	1377.0	1378.0	1379.0	1380.0	1381.0	1382.0	1383.0	1384.0	1385.0	1386.0	1387.0	1388.0	1389.0	1390.0	1391.0	1392.0	1393.0	1394.0	1395.0	1396.0	1397.0	1398.0	1399.0
+1400.0	1401.0	1402.0	1403.0	1404.0	1405.0	1406.0	1407.0	1408.0	1409.0	1410.0	1411.0	1412.0	1413.0	1414.0	1415.0	1416.0	1417.0	1418.0	1419.0	1420.0	1421.0	1422.0	1423.0	1424.0	1425.0	1426.0	1427.0	1428.0	1429.0	1430.0	1431.0	1432.0	1433.0	1434.0	1435.0	1436.0	1437.0	1438.0	1439.0	1440.0	1441.0	1442.0	1443.0	1444.0	1445.0	1446.0	1447.0	1448.0	1449.0	1450.0	1451.0	1452.0	1453.0	1454.0	1455.0	1456.0	1457.0	1458.0	1459.0	1460.0	1461.0	1462.0	1463.0	1464.0	1465.0	1466.0	1467.0	1468.0	1469.0	1470.0	1471.0	1472.0	1473.0	1474.0	1475.0	1476.0	1477.0	1478.0	1479.0	1480.0	1481.0	1482.0	1483.0	1484.0	1485.0	1486.0	1487.0	1488.0	1489.0	1490.0	1491.0	1492.0	1493.0	1494.0	1495.0	1496.0	1497.0	1498.0	1499.0
+1500.0	1501.0	1502.0	1503.0	1504.0	1505.0	1506.0	1507.0	1508.0	1509.0	1510.0	1511.0	1512.0	1513.0	1514.0	1515.0	1516.0	1517.0	1518.0	1519.0	1520.0	1521.0	1522.0	1523.0	1524.0	1525.0	1526.0	1527.0	1528.0	1529.0	1530.0	1531.0	1532.0	1533.0	1534.0	1535.0	1536.0	1537.0	1538.0	1539.0	1540.0	1541.0	1542.0	1543.0	1544.0	1545.0	1546.0	1547.0	1548.0	1549.0	1550.0	1551.0	1552.0	1553.0	1554.0	1555.0	1556.0	1557.0	1558.0	1559.0	1560.0	1561.0	1562.0	1563.0	1564.0	1565.0	1566.0	1567.0	1568.0	1569.0	1570.0	1571.0	1572.0	1573.0	1574.0	1575.0	1576.0	1577.0	1578.0	1579.0	1580.0	1581.0	1582.0	1583.0	1584.0	1585.0	1586.0	1587.0	1588.0	1589.0	1590.0	1591.0	1592.0	1593.0	1594.0	1595.0	1596.0	1597.0	1598.0	1599.0
+1600.0	1601.0	1602.0	1603.0	1604.0	1605.0	1606.0	1607.0	1608.0	1609.0	1610.0	1611.0	1612.0	1613.0	1614.0	1615.0	1616.0	1617.0	1618.0	1619.0	1620.0	1621.0	1622.0	1623.0	1624.0	1625.0	1626.0	1627.0	1628.0	1629.0	1630.0	1631.0	1632.0	1633.0	1634.0	1635.0	1636.0	1637.0	1638.0	1639.0	1640.0	1641.0	1642.0	1643.0	1644.0	1645.0	1646.0	1647.0	1648.0	1649.0	1650.0	1651.0	1652.0	1653.0	1654.0	1655.0	1656.0	1657.0	1658.0	1659.0	1660.0	1661.0	1662.0	1663.0	1664.0	1665.0	1666.0	1667.0	1668.0	1669.0	1670.0	1671.0	1672.0	1673.0	1674.0	1675.0	1676.0	1677.0	1678.0	1679.0	1680.0	1681.0	1682.0	1683.0	1684.0	1685.0	1686.0	1687.0	1688.0	1689.0	1690.0	1691.0	1692.0	1693.0	1694.0	1695.0	1696.0	1697.0	1698.0	1699.0
+1700.0	1701.0	1702.0	1703.0	1704.0	1705.0	1706.0	1707.0	1708.0	1709.0	1710.0	1711.0	1712.0	1713.0	1714.0	1715.0	1716.0	1717.0	1718.0	1719.0	1720.0	1721.0	1722.0	1723.0	1724.0	1725.0	1726.0	1727.0	1728.0	1729.0	1730.0	1731.0	1732.0	1733.0	1734.0	1735.0	1736.0	1737.0	1738.0	1739.0	1740.0	1741.0	1742.0	1743.0	1744.0	1745.0	1746.0	1747.0	1748.0	1749.0	1750.0	1751.0	1752.0	1753.0	1754.0	1755.0	1756.0	1757.0	1758.0	1759.0	1760.0	1761.0	1762.0	1763.0	1764.0	1765.0	1766.0	1767.0	1768.0	1769.0	1770.0	1771.0	1772.0	1773.0	1774.0	1775.0	1776.0	1777.0	1778.0	1779.0	1780.0	1781.0	1782.0	1783.0	1784.0	1785.0	1786.0	1787.0	1788.0	1789.0	1790.0	1791.0	1792.0	1793.0	1794.0	1795.0	1796.0	1797.0	1798.0	1799.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/firstlayer.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,9 @@
+-4.38397705861083	14.292813312163	-3.50113245239144	0.822254333007829	1.00150289648448	2.43591204698924	-0.356677013622828	-6.11947364969354	2.56281003005924	6.63909009032078	-0.78946499862756	4.69845868698249	0.555316773542253	1.14493347970535	-2.13170480396421	0.671242754395511	-1.24598424970653	2.35762885939	0.808249063291586	2.13338650412044	-0.442400711567299	0.185262494040311	2.11898976841304	1.33325569029047	-1.59297725345935	-0.966752781646448	3.58792591654639	1.66406580309397	0.63327385793388	-0.308925411126234	1.62030751470511	-0.551680746030133	0.481109445913889	-1.29522624182828	-1.2921145302749	1.35092954319461	0.357971803776218	0.602387478388324	-0.86450428384588	-0.253516849675122	-0.191991523300002	-1.23045693386899	1.10601149579208	0.474927307151347	0.0295127518668576	0.347320109574423	-0.124263697792595	-1.1355438083115	-0.408955132576027	0.652951279673313	-0.560853895759609	-1.50956633618222	-0.372228084801999	0.649248591501578	1.24501120925882	-0.333165552309464	-0.632289365875825	-0.489136074968853	0.606241184362324	-0.0697756202083343	0.723366081694609	0.269156075893411	-1.1927509857456	1.82685437466378	0.112075843817834	-0.393322613665142	1.28166028199521	-1.44150233543534	0.439168555592787	0.344017904319427	1.81395743926678	0.508805925557063	0.848238740356503	1.11258006953971	-0.54997200023266	0.809927913686388	-0.738427841761447	-0.453122730649697	-0.486373667035062	0.746360065063862	0.700920021470684	-0.313589192332652	-0.906138725835488	-0.661793483747946	-0.271124869295733	-0.00930238204411152	0.3215219758547	-1.25380192942129	-1.55728763598058	0.0952110940501214	0.00839453406532392	-0.0541448293428013	0.18477775291979	-0.62373646202135	-0.0772377796590389	-0.662366716574923	-1.03592409403641	-0.89249106169138	-0.717710251591651	0.776880357163071
+9.30281248024864	11.5335015413635	2.30875450845203	-1.38857898424223	1.03817215518254	3.6567570331059	10.4188385719381	-16.3128929934454	-3.60726875451658	13.7068591589974	1.33467070509089	5.38122487635218	0.0543994941205517	-2.70133427961325	0.0833615201988052	0.536168996886923	-0.0760546449729948	-0.78214225809622	-1.95248285633292	-0.326587425115489	-1.35500688419885	2.95434733271686	0.505653381720533	-0.295669096974786	2.26651004107081	3.53486650501347	3.220565758935	6.7321178798513	1.94091616482302	-1.69913768324206	-4.05100974370053	-1.27783882963281	-1.01355047824763	3.74963974715759	-2.58850482422048	6.8833099016512	0.662009356554069	3.44073177658161	-0.418512226093587	4.47846431563314	-1.74206293554388	1.84260608944111	-4.30015045993517	0.685087251537494	3.24882497326721	1.8095695466243	0.867087349923969	-3.63680218472816	4.1068657392081	-1.47022937993631	-5.04481250049395	1.16372912821134	-0.673610496402694	-0.480268341823079	-1.75373530199601	0.89984292745755	-0.685746934741278	1.35462132079302	-2.52570708801692	-2.74016842015935	-0.393885487708287	1.35180900874174	0.566787604497255	3.47016490744519	1.19410589958458	0.0954571935227406	0.465830133214735	0.969800327817249	-2.30608823177911	-1.36361346526534	-1.07384772734754	-1.28884764388441	-1.1808330583485	-2.23980854377317	-1.85162318607013	-0.069323155428631	-0.398294053191192	0.533970283418857	0.996857378845262	0.0816831777715224	0.444550338509664	-2.91836706827678	-0.267414770797715	-0.892474756707529	2.17409610136124	1.74372514825455	1.50066087410441	2.38996632942927	0.0469000573619218	-0.664299183380684	2.60790199917983	-2.40710478607531	1.24547812809717	2.41674046127559	-1.46444549406779	0.364174652919165	1.30109643082257	-0.577449382132677	-1.86505783133924	-1.99746975425092
+-5.89727512326108	-1.77246933119333	1.52782219208749	2.53511205650502	-2.53100068245452	-0.024300692685485	1.54330662794615	-2.74799503275627	-3.35444290166925	4.19511229947865	0.465153187650876	1.75331948382231	-1.16526308150911	-0.0943840089716619	-0.24095624876061	1.66521052849681	-2.11688113706039	-0.812191599443991	1.84008723741373	1.09605489701982	0.353335700092688	-0.523288451494122	-0.299012962148017	-2.88920874353573	-0.513481504763197	-2.21470284158116	0.416199869738419	-1.71617700908213	0.13685968824668	-0.489715075784864	-0.0102036078613937	-0.516945547789662	0.352617930831872	-0.172077340456524	0.196453120465679	1.22308205746272	-1.4849640784569	-0.243377392627181	0.463503859887059	1.04264188740704	-0.331273064367236	-1.0125587303605	-0.680700905917006	-0.511146692498302	0.140274079827094	1.22492893349224	0.855720140552588	0.382720446624883	-1.30875493636543	-0.500274960509595	0.700372605279355	-0.812474995526137	0.149519909761233	0.533411145285562	1.67008404672273	0.928331439602055	1.02096341369662	-0.261832925209925	0.629853148817829	1.7219125379708	1.00569983479743	-0.00450402234155931	-0.341416796091634	-1.3872557790274	1.80055359739341	-0.495374006741585	1.89145980335166	-0.693472867202045	-1.50974963506413	-1.2209076341959	-0.42594436412776	0.632021725852767	1.94342611009792	-0.540923793215291	0.201663676681874	0.163531142284654	0.997291087405646	0.869073146379135	-0.143753031104283	0.675612490310951	1.42469798361898	-0.756276309215264	-0.654925014119027	-0.949160720897864	-1.64701975142294	-1.10655034901924	1.29407378748758	1.15840377994492	1.8067185575117	-0.835226683327202	1.5648561397647	0.204808545499026	1.84035824825071	-0.981778359868067	-0.0289116785905805	1.23206606204954	-0.546713726320213	-0.629137661987508	-0.69213855880832	0.896728867097452
+-5.29270675301426	9.90705208795245	-5.64389382322256	-0.23270936454856	-8.00668157348614	-3.7826928671003	8.18196260183207	-5.73131556261441	9.61491655549755	1.65872404583472	0.6931540256981	-0.375292304271315	2.50804219920716	-1.86911671797384	-0.932517291897027	1.77919191661771	2.80170359222648	0.738113125484133	0.708504101366545	1.22066296829662	2.10045001006274	0.182322661637994	1.67434719528026	0.935397923906938	-2.561768409605	0.581039221769399	-0.407966302556971	-0.939901920959218	-0.590698586514989	-0.718006228836953	0.0996258132335209	-1.07932947402778	0.13450499684297	0.945797885637747	0.166188540192427	1.60684758988644	0.604234735179785	-0.463220916481101	0.231103189936207	0.119622602387229	0.71354769917271	1.65722623058665	-0.741448027546473	0.259192208047517	0.8291468631134	-0.117263739306486	-0.147582941706287	0.615321152218305	-0.551001006157352	0.621370181538221	0.311858058587134	2.65627826972861	-0.409401739107173	-0.889254236720799	-0.316240220054344	1.65029514443773	-0.329299152922808	1.1443748905888	1.09697477595742	1.0950696352531	0.517103431102195	-0.57854363786886	-1.05143518912101	-0.597195894417476	-1.52272606255708	-1.45996052619658	-0.16369116403685	1.25171548375323	1.32264262600894	-0.156879567237048	0.10642556389866	0.198583595909365	-0.612200116456148	0.850003590942363	-0.362186192823249	0.434242782164353	0.025143942334855	-1.43084257833896	0.349051292219086	-1.10071268661716	-0.663298490158815	1.68031258466557	-0.763051031379906	-0.600493768630168	-1.18545167697973	1.57551925143202	-1.30181346792223	0.728548494165308	2.34566406049576	-0.1884974788404	0.0118345339438655	-1.92948304988134	-1.27153538096398	-1.58327361831734	-0.260849294996154	1.03685648548191	-0.0437721407831781	1.00014006822958	-0.938662826224149	-0.681755709297571
+-6.08405321020853	-7.4364434223963	-0.373159059998994	1.85654867754332	-0.066646375393358	-0.812924879075801	3.77256207671638	-4.45857785752643	-1.17510687896568	5.36398845214791	-0.0444852947462604	1.68800891479541	-1.02343129106454	-0.0291781173718133	0.43336514102907	0.990488346010292	-0.390089117586027	-0.457623162821967	-0.226781546433054	-0.555218647277086	0.546384482359304	0.42572738657391	-0.446772412376349	0.398548443431641	1.20781385870181	1.51524917822676	-0.725894206140178	1.18804156528341	-0.291832474002874	-0.27334865010719	0.724820114357118	-0.754521181462694	-0.219142473146785	-0.547687176358784	0.224136403157904	1.34562257942705	0.0199235207085279	0.69339897171333	0.455378706946114	0.570216029696232	-0.743264335483396	0.430965842886427	0.956994648442376	-0.149622852814064	0.422662124186914	-0.667500360398019	0.126155771988897	0.189734014278429	-0.495090800986108	1.45314992106433	0.279597362279374	0.00420831221791874	0.0684328927904376	0.564534608052136	0.180566928063181	-0.212532593283124	0.165962191853296	-0.737236941067074	1.00374592433454	-0.489192171197334	0.0539789704682752	-0.0245445454807236	-0.810706903383208	0.397757427163805	-0.834737274946879	1.31784747773081	-0.863296976786124	0.791009220921894	-0.115535163453668	0.239851976966603	0.822806870619781	1.46817239457077	-0.0124083750837263	0.421701646259027	0.606800925633079	-0.615348044902974	0.00771763746167571	-1.28413167291888	1.25188349695723	-1.2725572369587	0.666176677913971	0.270927203640637	0.214522143842674	0.462719837122182	-0.177097322640291	0.0588285152479112	-1.35804255884329	0.693252357054687	0.632882198947294	-1.16659093085466	-0.00943380228354805	0.152370596963306	-0.0930460025434874	0.371587071821932	0.398461629580755	2.0789838212624	0.239120325286236	-0.697665704632893	-1.04006734705331	-1.1903200870504
+-4.35898581592111	10.8295807087292	-9.33885578536902	-3.88278806546879	2.57336996898482	-0.787128307301999	4.49394697617967	0.987317973527029	-0.225552365005083	4.79243994675665	0.307132342851648	-0.00145140061122141	-1.85227464816376	-0.0146708390591366	1.58989123998554	-0.9849461656821	0.63142833831129	0.387885029309716	1.52980092070315	-3.23439503156197	3.32085985699086	-0.0421136588930143	-0.283455894117478	-2.34109197749086	-0.424720533947467	-1.02447961214719	1.1122173946011	-1.01924324644954	0.80461628206255	0.232354115524204	0.752233505845615	1.1628978386598	0.301075834919574	-0.694363806595065	-0.899225283748419	0.543510566685045	0.893707801826774	-0.944916816404443	-1.36393372385435	1.65431576964293	0.746573599498895	-0.102838075889582	-0.5515109990147	-1.54827280151299	-0.445191727598828	-0.486932562166509	0.616319749247666	-0.0302575922813826	-1.02185774427578	-0.736444939587494	0.46764320276055	1.0904994570631	0.748029573521368	1.24714317270018	-0.650648493309113	1.18928361183252	-2.60324984503231	0.633787352775379	1.41517229407607	-0.159125715586533	1.0219321983147	-0.831168755689713	1.30942153193657	0.0753733563214212	0.285734058354515	-0.844644707777072	-0.236157958311837	0.20122330702161	1.01999662814264	1.86348523432828	0.216795698696114	-1.32687878081284	-0.392155900831159	1.03431815144232	0.124669010882415	0.474592236603064	0.542919054766528	-1.88877707853684	-1.65148897922194	2.40220393457081	0.548940519345852	-0.256496494870999	0.191515904091741	2.15710802253758	-0.205817145081161	1.05839422546064	1.68258415026592	-0.0918278059169231	1.90068387612529	-0.817314890418665	0.715322848822701	-2.51914068778904	-0.695236426531822	1.05884466477253	0.6475293063184	-0.167640902530503	0.0931156641327686	-1.37860166201551	-1.4994346966975	-1.17559042360564
+-5.44956627518923	0.200884241359212	-0.0940099392362255	0.391424565921512	-4.42294103296365	2.02612071023864	-1.9620071791874	-4.26175597130446	0.8998793535643	3.76053900904884	-1.6361298996455	2.36042379179368	-2.75819699300257	-0.100530502966349	-0.0427288135063918	0.0640031148216666	0.523327742271745	0.160640450650541	-1.0380547955777	0.550687662279054	-0.527266599351878	1.3816058202807	-2.69254136642811	-0.611084358977462	-0.935089408016054	-0.0387188817465848	0.793995944833708	-1.12785316556236	0.445937400816127	-0.946557945637926	1.18257558164449	-1.34233534254901	0.0176311421070648	-0.224900754574182	-0.204023222723773	1.51743434767516	-0.499316194896609	-0.116333597690277	1.02079557154874	1.6780373761605	0.171333151844323	-1.34382266831776	0.00270449514108322	1.29347313329421	0.896723180471322	-0.634461498200752	-0.213229675671139	0.785371380619926	-1.73220953509193	-1.53657066969688	-0.355849318354773	-1.24074606851403	0.136828779405145	0.97972003690276	0.0368991085138718	0.759313802193281	-0.0299124672475207	-0.0126005138019731	1.86019501588837	-0.0193050844578417	-0.370387588851618	-0.335589748476321	1.51063959473573	-0.32446285310899	-0.0420484344751731	1.03468246820123	1.15195012057021	-0.7585649009828	0.0340758533177857	-1.76245837695789	1.1953234508049	0.148246471218968	-0.465408959424267	-1.93276565033051	-0.601507670674328	0.561693178023859	-0.344148325356987	-1.76155715131425	1.53586806269923	-0.973497071015107	-0.0154265589569301	0.389711467291695	-0.239877266341895	0.352795111764336	-0.190135198230446	-0.208684600336429	2.07918244700086	-0.361025972011884	1.63078492845337	0.488804843489253	-0.682220518809875	-0.29463668542297	0.311427730874536	0.503090238195356	-0.373064491000882	0.23417554807577	-1.48465915072341	-1.46085021332334	-0.495461794448377	-0.17775442234612
+-3.97575208570735	11.0544858387352	7.6173060428113	6.63048929774542	-5.30994749122935	1.88722422257416	4.09251614216244	1.44648639362641	-7.25006907798796	6.86869361179653	0.491494050662433	-2.25651388279331	9.5161454340774	1.01476184398758	2.5399705796852	-2.21669881532076	3.98394683759498	3.59383510388346	6.12746355517479	-0.715726354893143	3.55159403974729	-1.11574398116924	-0.525929195057429	0.878154489745832	-0.230493171744922	0.714464510169232	-0.157245107145587	-3.4342599800683	0.48505980459346	0.702993897575898	-0.135378631070949	2.07954004197705	-0.690953937097613	1.27624456885549	1.21947693928713	1.65808520486344	0.961593556571414	-0.311912078906821	-0.188898767072046	-0.840060825549656	-1.12921186104506	1.56017494876464	0.411131589159066	-0.0521633935484305	-1.69684514175225	-0.0333681471142678	-0.13906225301883	1.24899138448782	-0.313535620881124	-0.310399053687893	0.998855535319549	-0.491386912744097	-2.65588822465539	-0.262301430974959	-0.37741200187771	-0.41429490709306	-0.561255237373123	-1.15276356159977	2.78298825141619	-0.502905861300848	-0.675640036112791	0.861407188085173	0.670870463440124	1.79627949867291	-1.49071314746396	1.10513353172237	0.892902985092724	-0.050023000293664	-2.0951156395428	-1.56875762272546	0.361989901125448	-0.225302477699307	0.169862551615696	-0.49530667266779	0.458175186664475	-1.32231097560469	0.786081372282524	-0.0484494603142322	0.706878176692001	1.15487020448148	0.531640766037383	-0.138810686002109	0.591943064902141	1.1023101065439	1.76277780537503	-0.905355575172113	0.134769770511889	-0.497015408904865	-0.742656863985804	-0.067343788917104	-0.540927632084057	-0.0580727941856462	-1.0462842718808	-0.00500540976328367	-0.824608358220491	-1.44352688132908	1.75740458742792	-0.44311879378313	-0.662584623920899	0.888462747166643
+-5.277006254183	2.42397087953038	-0.943798001822603	2.85780940799815	2.36895039654097	-2.69659967635116	1.54629605482182	-8.96928156931566	-1.64262157483957	1.43852747962271	-0.967981915016056	-0.390735428021631	-2.15024133526923	0.277271702300901	1.8053039804015	-0.535107559431625	1.67768924818208	-0.421010853147353	-1.16464550016846	-0.0251453460136133	0.436658055348297	-0.29540721194163	0.333748713475055	-0.723208532365344	0.471110811941787	0.726089991234918	-0.157382569241171	-0.379234094421878	0.748812558274635	-0.41301464848253	0.566057622213117	-1.64460356067673	0.891204658261791	-0.34932773880327	-1.30922369726531	-0.173573387498366	0.8056807178332	0.208881576008633	-1.60357889692679	0.908540313457729	-0.292428392920166	-0.0118489017469322	-0.891712950604345	1.16207204758746	0.430624050805364	-0.410051657015908	0.730349459202633	-0.331488261254584	-1.11548393909722	0.956994457204229	-0.175931934021692	-1.2036342551925	-0.231987307226876	0.750428558384009	1.32527020615915	-0.0420682884240139	-0.092958898049259	-0.0122267448532016	0.726126639304472	-0.694555932842187	-0.262226740797341	-1.0291540856062	0.0793211050194524	-0.670890710123743	2.29978649016219	-1.04786389277271	0.0673332449001132	-0.0371298860750165	-0.190086855611152	0.569211538833251	0.919033137444811	0.0635277673597158	1.00004676925338	0.463824012820739	-0.661533287421813	-0.532636001812366	0.13594592076042	0.353092106176299	0.362734586198694	0.648858597916376	-0.947487352382305	-0.890204579930725	-0.481659475836321	-0.382386249884642	-0.565389965376474	0.69470847650723	0.565209012057139	-0.594122862421382	0.374110007433118	0.906000246931211	1.14643222017558	-0.864426844788516	-0.107902667694253	-1.33878812133165	-0.648727117620733	-0.682898186419176	0.152703116395545	1.18647033835958	-0.730347642632863	0.355381103259185
Binary file test-data/loomtest.loom has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/rows.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,10 @@
+Gene	Protein	Testing	Testing2
+0	0	3	15
+1	1	4	16
+2	2	5	17
+3	3	6	18
+4	4	7	19
+5	5	8	20
+6	6	9	21
+7	7	10	22
+8	8	11	23
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/secondlayer.tsv	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,9 @@
+0.0	1.0	2.0	3.0	4.0	5.0	6.0	7.0	8.0	9.0	10.0	11.0	12.0	13.0	14.0	15.0	16.0	17.0	18.0	19.0	20.0	21.0	22.0	23.0	24.0	25.0	26.0	27.0	28.0	29.0	30.0	31.0	32.0	33.0	34.0	35.0	36.0	37.0	38.0	39.0	40.0	41.0	42.0	43.0	44.0	45.0	46.0	47.0	48.0	49.0	50.0	51.0	52.0	53.0	54.0	55.0	56.0	57.0	58.0	59.0	60.0	61.0	62.0	63.0	64.0	65.0	66.0	67.0	68.0	69.0	70.0	71.0	72.0	73.0	74.0	75.0	76.0	77.0	78.0	79.0	80.0	81.0	82.0	83.0	84.0	85.0	86.0	87.0	88.0	89.0	90.0	91.0	92.0	93.0	94.0	95.0	96.0	97.0	98.0	99.0
+100.0	101.0	102.0	103.0	104.0	105.0	106.0	107.0	108.0	109.0	110.0	111.0	112.0	113.0	114.0	115.0	116.0	117.0	118.0	119.0	120.0	121.0	122.0	123.0	124.0	125.0	126.0	127.0	128.0	129.0	130.0	131.0	132.0	133.0	134.0	135.0	136.0	137.0	138.0	139.0	140.0	141.0	142.0	143.0	144.0	145.0	146.0	147.0	148.0	149.0	150.0	151.0	152.0	153.0	154.0	155.0	156.0	157.0	158.0	159.0	160.0	161.0	162.0	163.0	164.0	165.0	166.0	167.0	168.0	169.0	170.0	171.0	172.0	173.0	174.0	175.0	176.0	177.0	178.0	179.0	180.0	181.0	182.0	183.0	184.0	185.0	186.0	187.0	188.0	189.0	190.0	191.0	192.0	193.0	194.0	195.0	196.0	197.0	198.0	199.0
+200.0	201.0	202.0	203.0	204.0	205.0	206.0	207.0	208.0	209.0	210.0	211.0	212.0	213.0	214.0	215.0	216.0	217.0	218.0	219.0	220.0	221.0	222.0	223.0	224.0	225.0	226.0	227.0	228.0	229.0	230.0	231.0	232.0	233.0	234.0	235.0	236.0	237.0	238.0	239.0	240.0	241.0	242.0	243.0	244.0	245.0	246.0	247.0	248.0	249.0	250.0	251.0	252.0	253.0	254.0	255.0	256.0	257.0	258.0	259.0	260.0	261.0	262.0	263.0	264.0	265.0	266.0	267.0	268.0	269.0	270.0	271.0	272.0	273.0	274.0	275.0	276.0	277.0	278.0	279.0	280.0	281.0	282.0	283.0	284.0	285.0	286.0	287.0	288.0	289.0	290.0	291.0	292.0	293.0	294.0	295.0	296.0	297.0	298.0	299.0
+300.0	301.0	302.0	303.0	304.0	305.0	306.0	307.0	308.0	309.0	310.0	311.0	312.0	313.0	314.0	315.0	316.0	317.0	318.0	319.0	320.0	321.0	322.0	323.0	324.0	325.0	326.0	327.0	328.0	329.0	330.0	331.0	332.0	333.0	334.0	335.0	336.0	337.0	338.0	339.0	340.0	341.0	342.0	343.0	344.0	345.0	346.0	347.0	348.0	349.0	350.0	351.0	352.0	353.0	354.0	355.0	356.0	357.0	358.0	359.0	360.0	361.0	362.0	363.0	364.0	365.0	366.0	367.0	368.0	369.0	370.0	371.0	372.0	373.0	374.0	375.0	376.0	377.0	378.0	379.0	380.0	381.0	382.0	383.0	384.0	385.0	386.0	387.0	388.0	389.0	390.0	391.0	392.0	393.0	394.0	395.0	396.0	397.0	398.0	399.0
+400.0	401.0	402.0	403.0	404.0	405.0	406.0	407.0	408.0	409.0	410.0	411.0	412.0	413.0	414.0	415.0	416.0	417.0	418.0	419.0	420.0	421.0	422.0	423.0	424.0	425.0	426.0	427.0	428.0	429.0	430.0	431.0	432.0	433.0	434.0	435.0	436.0	437.0	438.0	439.0	440.0	441.0	442.0	443.0	444.0	445.0	446.0	447.0	448.0	449.0	450.0	451.0	452.0	453.0	454.0	455.0	456.0	457.0	458.0	459.0	460.0	461.0	462.0	463.0	464.0	465.0	466.0	467.0	468.0	469.0	470.0	471.0	472.0	473.0	474.0	475.0	476.0	477.0	478.0	479.0	480.0	481.0	482.0	483.0	484.0	485.0	486.0	487.0	488.0	489.0	490.0	491.0	492.0	493.0	494.0	495.0	496.0	497.0	498.0	499.0
+500.0	501.0	502.0	503.0	504.0	505.0	506.0	507.0	508.0	509.0	510.0	511.0	512.0	513.0	514.0	515.0	516.0	517.0	518.0	519.0	520.0	521.0	522.0	523.0	524.0	525.0	526.0	527.0	528.0	529.0	530.0	531.0	532.0	533.0	534.0	535.0	536.0	537.0	538.0	539.0	540.0	541.0	542.0	543.0	544.0	545.0	546.0	547.0	548.0	549.0	550.0	551.0	552.0	553.0	554.0	555.0	556.0	557.0	558.0	559.0	560.0	561.0	562.0	563.0	564.0	565.0	566.0	567.0	568.0	569.0	570.0	571.0	572.0	573.0	574.0	575.0	576.0	577.0	578.0	579.0	580.0	581.0	582.0	583.0	584.0	585.0	586.0	587.0	588.0	589.0	590.0	591.0	592.0	593.0	594.0	595.0	596.0	597.0	598.0	599.0
+600.0	601.0	602.0	603.0	604.0	605.0	606.0	607.0	608.0	609.0	610.0	611.0	612.0	613.0	614.0	615.0	616.0	617.0	618.0	619.0	620.0	621.0	622.0	623.0	624.0	625.0	626.0	627.0	628.0	629.0	630.0	631.0	632.0	633.0	634.0	635.0	636.0	637.0	638.0	639.0	640.0	641.0	642.0	643.0	644.0	645.0	646.0	647.0	648.0	649.0	650.0	651.0	652.0	653.0	654.0	655.0	656.0	657.0	658.0	659.0	660.0	661.0	662.0	663.0	664.0	665.0	666.0	667.0	668.0	669.0	670.0	671.0	672.0	673.0	674.0	675.0	676.0	677.0	678.0	679.0	680.0	681.0	682.0	683.0	684.0	685.0	686.0	687.0	688.0	689.0	690.0	691.0	692.0	693.0	694.0	695.0	696.0	697.0	698.0	699.0
+700.0	701.0	702.0	703.0	704.0	705.0	706.0	707.0	708.0	709.0	710.0	711.0	712.0	713.0	714.0	715.0	716.0	717.0	718.0	719.0	720.0	721.0	722.0	723.0	724.0	725.0	726.0	727.0	728.0	729.0	730.0	731.0	732.0	733.0	734.0	735.0	736.0	737.0	738.0	739.0	740.0	741.0	742.0	743.0	744.0	745.0	746.0	747.0	748.0	749.0	750.0	751.0	752.0	753.0	754.0	755.0	756.0	757.0	758.0	759.0	760.0	761.0	762.0	763.0	764.0	765.0	766.0	767.0	768.0	769.0	770.0	771.0	772.0	773.0	774.0	775.0	776.0	777.0	778.0	779.0	780.0	781.0	782.0	783.0	784.0	785.0	786.0	787.0	788.0	789.0	790.0	791.0	792.0	793.0	794.0	795.0	796.0	797.0	798.0	799.0
+800.0	801.0	802.0	803.0	804.0	805.0	806.0	807.0	808.0	809.0	810.0	811.0	812.0	813.0	814.0	815.0	816.0	817.0	818.0	819.0	820.0	821.0	822.0	823.0	824.0	825.0	826.0	827.0	828.0	829.0	830.0	831.0	832.0	833.0	834.0	835.0	836.0	837.0	838.0	839.0	840.0	841.0	842.0	843.0	844.0	845.0	846.0	847.0	848.0	849.0	850.0	851.0	852.0	853.0	854.0	855.0	856.0	857.0	858.0	859.0	860.0	861.0	862.0	863.0	864.0	865.0	866.0	867.0	868.0	869.0	870.0	871.0	872.0	873.0	874.0	875.0	876.0	877.0	878.0	879.0	880.0	881.0	882.0	883.0	884.0	885.0	886.0	887.0	888.0	889.0	890.0	891.0	892.0	893.0	894.0	895.0	896.0	897.0	898.0	899.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tsv_to_loompy.py	Mon Jan 06 13:45:13 2020 -0500
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+"""This module converts a tsv file into a binary loom file"""
+
+import argparse
+import os
+
+import loompy
+import numpy as np
+
+parser = argparse.ArgumentParser(description="Loompy file converter flags")
+parser.add_argument('--VERSION', action='version', version='%(prog)s 0.1.0',
+                    help="Displays tool version")
+parser.add_argument('--rowfile', '-r', help="File of row attributes & values")
+parser.add_argument('--colfile', '-c',
+                    help="File of column attributes and values")
+parser.add_argument('--output', '-o', help="Output file name")
+parser.add_argument('--files', '-f', nargs='*',
+                    help="Input tsv files. First file becomes main layer.")
+args = parser.parse_args()
+
+colsfile = args.colfile
+rowsfile = args.rowfile
+if args.output:
+    filename = args.output
+else:
+    filename = "converted.loom"
+alldata = args.files
+alayers = []
+layernames = []
+rowdict = {}
+coldict = {}
+
+#  Creates dictionary based on row file
+#  For each attribute:
+#  Attribute: [attribute values]
+with open(rowsfile, "r") as rows:
+    count = 0
+    for line in rows:
+        line = line.strip().split("\t")
+        if count == 0:  # First time through
+            row_attributes = line
+            for x in row_attributes:
+                rowdict[x] = []
+            count += 1
+        else:
+            for x in range(0, len(line)):
+                rowdict[row_attributes[x]].append(line[x])
+#  Same as above, but for columns
+with open(colsfile, "r") as cols:
+    count = 0
+    for line in cols:
+        line = line.replace('\"', "")
+        line = line.replace(' ', "")
+        line = line.strip().split("\t")
+        if count == 0:  # First time through
+            col_attributes = line
+            for x in col_attributes:
+                coldict[x] = []
+            count += 1
+        else:
+            for x in range(0, len(line)):
+                coldict[col_attributes[x]].append(line[x])
+#  Finding dimensions for the loom layers
+rowshape = len(rowdict[list(rowdict.keys())[0]])
+colshape = len(coldict[list(coldict.keys())[0]])
+
+#  Creates a list with each element being entire matrix of
+#  each layer file as floats
+for file in range(0, len(alldata)):
+    layer = alldata[file][:-4]
+    layer = layer.split("/")[-1]
+    if layer == "":
+        raise Exception("Please only use named files")
+    layernames.append(layer)
+    cfile = alldata[file]
+    with open(cfile, "r") as tsv:
+        cmatrix = []
+        for line in tsv:
+            line = line.strip().split("\t")
+            line = [float(i) for i in line]
+            cmatrix += line
+        alayers.append(cmatrix)
+
+#  Loompy cannot overwright existing files. If somehow it finds
+#  a second file with the same name, it must be deleted
+if os.path.isfile(filename):
+    os.remove(filename)
+#  To create the file properly, the first row and column attributes must be
+#  added separately in the form of individual dictionaries
+row_attrs = {row_attributes[0]: np.asarray(rowdict[row_attributes[0]])}
+col_attrs = {col_attributes[0]: np.asarray(coldict[col_attributes[0]])}
+matrix = np.asarray(alayers[0])
+matrix = matrix.astype(float)
+matrix = matrix.reshape(rowshape, colshape)
+#  Creation of initial loom file
+if "loom" not in filename[-5:]:
+    filename = filename + ".loom"
+loompy.create(filename, matrix, row_attrs, col_attrs)
+#  Adding all row and column attributes, then all layers
+with loompy.connect(filename) as loomfile:
+    for x in row_attributes:
+        loomfile.ra[x] = rowdict[x]
+    for y in col_attributes:
+        loomfile.ca[y] = coldict[y]
+    for z in range(1, len(alayers)):
+        matrix = np.asarray(alayers[z])
+        matrix = matrix.astype(float)
+        matrix = matrix.reshape(rowshape, colshape)
+        loomfile[layernames[z]] = matrix