about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--misc/notes.txt6
-rwxr-xr-xwqflask/base/data_set.py16
-rwxr-xr-xwqflask/wqflask/marker_regression/marker_regression.py159
-rw-r--r--wqflask/wqflask/my_pylmm/data/genofile_parser.py22
-rwxr-xr-x[-rw-r--r--]wqflask/wqflask/my_pylmm/pyLMM/lmm.py110
-rw-r--r--wqflask/wqflask/my_pylmm/run_pylmm.py77
-rw-r--r--wqflask/wqflask/static/new/css/bar_chart.css1
-rw-r--r--wqflask/wqflask/static/new/css/marker_regression.css9
-rw-r--r--wqflask/wqflask/static/new/javascript/bar_chart.coffee157
-rw-r--r--wqflask/wqflask/static/new/javascript/bar_chart.js80
-rw-r--r--wqflask/wqflask/static/new/javascript/chr_manhattan_plot.coffee211
-rw-r--r--wqflask/wqflask/static/new/javascript/chr_manhattan_plot.js206
-rw-r--r--wqflask/wqflask/static/new/javascript/histogram.coffee106
-rw-r--r--wqflask/wqflask/static/new/javascript/histogram.js118
-rw-r--r--wqflask/wqflask/static/new/javascript/marker_regression.coffee688
-rw-r--r--wqflask/wqflask/static/new/javascript/marker_regression.js582
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait.coffee21
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait.js9
-rw-r--r--wqflask/wqflask/static/new/packages/DataTables/js/dataTables.naturalSort.js56
-rw-r--r--wqflask/wqflask/templates/index_page.html6
-rw-r--r--wqflask/wqflask/templates/interval_mapping.html1
-rw-r--r--wqflask/wqflask/templates/marker_regression.html29
-rw-r--r--wqflask/wqflask/templates/show_trait.html40
-rw-r--r--wqflask/wqflask/templates/show_trait_edit_data.html132
-rw-r--r--wqflask/wqflask/templates/show_trait_mapping_tools.html2
-rw-r--r--wqflask/wqflask/templates/show_trait_statistics_new.html18
-rw-r--r--wqflask/wqflask/views.py7
27 files changed, 2073 insertions, 796 deletions
diff --git a/misc/notes.txt b/misc/notes.txt
index 5a43ab8a..f8ce2759 100644
--- a/misc/notes.txt
+++ b/misc/notes.txt
@@ -273,6 +273,12 @@ grep -ir (search string) (directory)
 
 ===========================================
 
+Command line arguments:
+
+Use argparse to deal with command line arguments (instead of argv or optparse)
+
+===========================================
+
 Change owner/group:
 
 chown zas1024 somefile (change owner of somefile to zas1024)
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index fbe78d5d..3deaa655 100755
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -168,13 +168,13 @@ class Markers(object):
         
         for marker, p_value in itertools.izip(self.markers, p_values):
             marker['p_value'] = p_value
-            if math.isnan(marker['p_value']):
-                print("p_value is:", marker['p_value'])
-            marker['lod_score'] = -math.log10(marker['p_value'])
-            #Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
-            marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61
-        
-        
+            if math.isnan(marker['p_value']) or marker['p_value'] <= 0:
+                marker['lod_score'] = 0
+                marker['lrs_value'] = 0
+            else:
+                marker['lod_score'] = -math.log10(marker['p_value'])
+                #Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
+                marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61
 
 
 class HumanMarkers(Markers):
@@ -184,6 +184,7 @@ class HumanMarkers(Markers):
         self.markers = []
         for line in marker_data_fh:
             splat = line.strip().split()
+            #print("splat:", splat)
             marker = {}
             marker['chr'] = int(splat[0])
             marker['name'] = splat[1]
@@ -203,6 +204,7 @@ class HumanMarkers(Markers):
         #    #Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
         #    marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61
         
+        print("p_values2:", p_values)
         super(HumanMarkers, self).add_pvalues(p_values)
         
         with Bench("deleting markers"):
diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py
index 006c586b..0dd55729 100755
--- a/wqflask/wqflask/marker_regression/marker_regression.py
+++ b/wqflask/wqflask/marker_regression/marker_regression.py
@@ -7,16 +7,20 @@ from pprint import pformat as pf
 
 import string
 import sys
+import datetime
 import os
 import collections
+import uuid
 
 import numpy as np
 from scipy import linalg
 
-import simplejson as json
+import cPickle as pickle
 
-#from redis import Redis
+import simplejson as json
 
+from redis import Redis
+Redis = Redis()
 
 from base.trait import GeneralTrait
 from base import data_set
@@ -38,7 +42,7 @@ class MarkerRegression(object):
 
         helper_functions.get_species_dataset_trait(self, start_vars)
 
-        tempdata = temp_data.TempData(temp_uuid)
+        #tempdata = temp_data.TempData(temp_uuid)
         
         self.samples = [] # Want only ones with values
         self.vals = []
@@ -48,7 +52,9 @@ class MarkerRegression(object):
             self.samples.append(str(sample))
             self.vals.append(value)
  
-        self.gen_data(tempdata)
+        #self.qtl_results = self.gen_data(tempdata)
+        self.qtl_results = self.gen_data(str(temp_uuid))
+        self.lod_cutoff = self.get_lod_score_cutoff()
 
         #Get chromosome lengths for drawing the manhattan plot
         chromosome_mb_lengths = {}
@@ -61,15 +67,23 @@ class MarkerRegression(object):
         )
 
 
-    def gen_data(self, tempdata):
+    #def gen_data(self, tempdata):
+    def gen_data(self, temp_uuid):
         """Generates p-values for each marker"""
 
         self.dataset.group.get_markers()
 
         pheno_vector = np.array([val == "x" and np.nan or float(val) for val in self.vals])
 
+        #lmm_uuid = str(uuid.uuid4())
+
+        key = "pylmm:input:" + temp_uuid
+        print("key is:", pf(key))
+        #with Bench("Loading cache"):
+        #    result = Redis.get(key)
+
         if self.dataset.group.species == "human":
-            p_values, t_stats = self.gen_human_results(pheno_vector, tempdata)
+            p_values, t_stats = self.gen_human_results(pheno_vector, key, temp_uuid)
         else:
             genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers]
             
@@ -77,24 +91,66 @@ class MarkerRegression(object):
             trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples)
             
             genotype_matrix = np.array(trimmed_genotype_data).T
+
+            #print("pheno_vector: ", pf(pheno_vector))
+            #print("genotype_matrix: ", pf(genotype_matrix))
+            #print("genotype_matrix.shape: ", pf(genotype_matrix.shape))
+
+            #params = {"pheno_vector": pheno_vector,
+            #            "genotype_matrix": genotype_matrix,
+            #            "restricted_max_likelihood": True,
+            #            "refit": False,
+            #            "temp_data": tempdata}
             
-            print("pheno_vector: ", pf(pheno_vector))
-            print("genotype_matrix: ", pf(genotype_matrix))
-            print("genotype_matrix.shape: ", pf(genotype_matrix.shape))
+            params = dict(pheno_vector = pheno_vector.tolist(),
+                        genotype_matrix = genotype_matrix.tolist(),
+                        restricted_max_likelihood = True,
+                        refit = False,
+                        temp_uuid = temp_uuid,
+                        
+                        # meta data
+                        timestamp = datetime.datetime.now().isoformat(),
+                        )
             
-            t_stats, p_values = lmm.run(
-                pheno_vector,
-                genotype_matrix,
-                restricted_max_likelihood=True,
-                refit=False,
-                temp_data=tempdata
-            )
-        
+            json_params = json.dumps(params)
+            print("json_params:", json_params)
+            Redis.set(key, json_params)
+            Redis.expire(key, 60*60)
+            print("before printing command")
+
+            command = 'python /home/zas1024/gene/wqflask/wqflask/my_pylmm/pyLMM/lmm.py --key {} --species {}'.format(key,
+                                                                                                                    "other")
+            print("command is:", command)
+            print("after printing command")
+
+            os.system(command)
+
+            #t_stats, p_values = lmm.run(key)
+            #lmm.run(key)
+            
+            json_results = Redis.blpop("pylmm:results:" + temp_uuid, 45*60)
+            results = json.loads(json_results[1])
+            p_values = results['p_values']
+            t_stats = results['t_stats']
+            
+            #t_stats, p_values = lmm.run(
+            #    pheno_vector,
+            #    genotype_matrix,
+            #    restricted_max_likelihood=True,
+            #    refit=False,
+            #    temp_data=tempdata
+            #)
+            #print("p_values:", p_values)
+
         self.dataset.group.markers.add_pvalues(p_values)
-        self.qtl_results = self.dataset.group.markers.markers
+        
+        self.get_lod_score_cutoff()
+        
+        return self.dataset.group.markers.markers
 
 
-    def gen_human_results(self, pheno_vector, tempdata):
+    #def gen_human_results(self, pheno_vector, tempdata):
+    def gen_human_results(self, pheno_vector, key, temp_uuid):
         file_base = os.path.join(webqtlConfig.PYLMM_PATH, self.dataset.group.name)
 
         plink_input = input.plink(file_base, type='b')
@@ -105,16 +161,62 @@ class MarkerRegression(object):
         kinship_matrix = np.fromfile(open(file_base + '.kin','r'),sep=" ")
         kinship_matrix.resize((len(plink_input.indivs),len(plink_input.indivs)))
 
-        p_values, t_stats = lmm.run_human(
-                pheno_vector,
-                covariate_matrix,
-                input_file_name,
-                kinship_matrix,
-                loading_progress=tempdata
-            )
+        print("Before creating params")
+
+        params = dict(pheno_vector = pheno_vector.tolist(),
+                    covariate_matrix = covariate_matrix.tolist(),
+                    input_file_name = input_file_name,
+                    kinship_matrix = kinship_matrix.tolist(),
+                    refit = False,
+                    temp_uuid = temp_uuid,
+                        
+                    # meta data
+                    timestamp = datetime.datetime.now().isoformat(),
+                    )
+        
+        print("After creating params")
+        
+        json_params = json.dumps(params)
+        Redis.set(key, json_params)
+        Redis.expire(key, 60*60)
+
+        print("Before creating the command")
+
+        command = 'python /home/zas1024/gene/wqflask/wqflask/my_pylmm/pyLMM/lmm.py --key {} --species {}'.format(key,
+                                                                                                                "human")
+        
+        print("command is:", command)
+        
+        os.system(command)
+        
+        json_results = Redis.blpop("pylmm:results:" + temp_uuid, 45*60)
+        results = json.loads(json_results[1])
+        t_stats = results['t_stats']
+        p_values = results['p_values']
+        
+
+        #p_values, t_stats = lmm.run_human(key)
+
+        #p_values, t_stats = lmm.run_human(
+        #        pheno_vector,
+        #        covariate_matrix,
+        #        input_file_name,
+        #        kinship_matrix,
+        #        loading_progress=tempdata
+        #    )
 
         return p_values, t_stats
 
+    def get_lod_score_cutoff(self):
+        high_qtl_count = 0
+        for marker in self.dataset.group.markers.markers:
+            if marker['lod_score'] > 2:
+                high_qtl_count += 1
+                
+        if high_qtl_count > 10000:
+            return 1
+        else:
+            return 2
 
     def identify_empty_samples(self):
         no_val_samples = []
@@ -157,6 +259,11 @@ def create_snp_iterator_file(group):
     with gzip.open(snp_file_base, "wb") as fh:
         pickle.dump(data, fh, pickle.HIGHEST_PROTOCOL)
 
+#if __name__ == '__main__':
+#    import cPickle as pickle
+#    import gzip
+#    create_snp_iterator_file("HLC")
+    
 if __name__ == '__main__':
     import cPickle as pickle
     import gzip
diff --git a/wqflask/wqflask/my_pylmm/data/genofile_parser.py b/wqflask/wqflask/my_pylmm/data/genofile_parser.py
index 4a647959..4ebadb6e 100644
--- a/wqflask/wqflask/my_pylmm/data/genofile_parser.py
+++ b/wqflask/wqflask/my_pylmm/data/genofile_parser.py
@@ -93,12 +93,12 @@ class ConvertGenoFile(object):
             this_marker = Marker()
             this_marker.name = row_items[1]
             this_marker.chr = row_items[0]
-            this_marker.cM = row_items[2]
+            #this_marker.cM = row_items[2]
             if self.mb_exists:
-                this_marker.Mb = row_items[3]
-                genotypes = row_items[4:]
-            else:
+                this_marker.Mb = row_items[2]
                 genotypes = row_items[3:]
+            else:
+                genotypes = row_items[2:]
             for item_count, genotype in enumerate(genotypes):
                 if genotype.upper() in self.configurations:
                     this_marker.genotypes.append(self.configurations[genotype.upper()])
@@ -106,8 +106,8 @@ class ConvertGenoFile(object):
                     this_marker.genotypes.append("NA")
                 
             #print("this_marker is:", pf(this_marker.__dict__))   
-                
-            self.markers.append(this_marker.__dict__)
+            if this_marker.chr == "14":
+                self.markers.append(this_marker.__dict__)
 
         with open(self.output_file, 'w') as fh:
             json.dump(self.markers, fh, indent="   ", sort_keys=True)
@@ -125,8 +125,8 @@ class ConvertGenoFile(object):
 
     def process_rows(self):
         for self.latest_row_pos, row in enumerate(self.input_fh):
-            if self.input_file.endswith(".geno.gz"):
-                print("row: ", row)
+            #if self.input_file.endswith(".geno.gz"):
+            #    print("row: ", row)
             self.latest_row_value = row
             # Take care of headers
             if not row.strip():
@@ -186,8 +186,10 @@ if __name__=="__main__":
     Old_Geno_Directory = """/home/zas1024/gene/web/genotypes/"""
     New_Geno_Directory = """/home/zas1024/gene/web/new_genotypes/"""
     #Input_File = """/home/zas1024/gene/web/genotypes/BXD.geno"""
-    #Output_File = """/home/zas1024/gene/wqflask/wqflask/pylmm/data/bxd.snps""" 
-    ConvertGenoFile.process_all(Old_Geno_Directory, New_Geno_Directory)
+    #Output_File = """/home/zas1024/gene/wqflask/wqflask/pylmm/data/bxd.snps"""
+    convertob = ConvertGenoFile("/home/zas1024/gene/web/genotypes/HSNIH.geno.gz", "/home/zas1024/gene/web/new_genotypes/HSNIH.json")
+    convertob.convert()
+    #ConvertGenoFile.process_all(Old_Geno_Directory, New_Geno_Directory)
     #ConvertGenoFiles(Geno_Directory)
     
     #process_csv(Input_File, Output_File)
\ No newline at end of file
diff --git a/wqflask/wqflask/my_pylmm/pyLMM/lmm.py b/wqflask/wqflask/my_pylmm/pyLMM/lmm.py
index 60d36b8d..a0ff31ef 100644..100755
--- a/wqflask/wqflask/my_pylmm/pyLMM/lmm.py
+++ b/wqflask/wqflask/my_pylmm/pyLMM/lmm.py
@@ -19,6 +19,7 @@ from __future__ import absolute_import, print_function, division
 
 import sys
 import time
+import argparse
 import uuid
 
 import numpy as np
@@ -27,6 +28,8 @@ from scipy import optimize
 from scipy import stats
 import pdb
 
+import simplejson as json
+
 import gzip
 import zlib
 import datetime
@@ -35,22 +38,34 @@ import simplejson as json
 
 from pprint import pformat as pf
 
+from redis import Redis
+Redis = Redis()
+
+import sys
+sys.path.append("/home/zas1024/gene/wqflask/")
+print("sys.path2:", sys.path)
+
 from utility.benchmark import Bench
 from utility import temp_data
 
 from wqflask.my_pylmm.pyLMM import chunks
 
-import redis
-Redis = redis.Redis()
 
 #np.seterr('raise')
 
+#def run_human(pheno_vector,
+#            covariate_matrix,
+#            plink_input_file,
+#            kinship_matrix,
+#            refit=False,
+#            loading_progress=None):
+
 def run_human(pheno_vector,
             covariate_matrix,
             plink_input_file,
             kinship_matrix,
             refit=False,
-            loading_progress=None):
+            tempdata=None):
 
     v = np.isnan(pheno_vector)
     keep = True - v
@@ -58,17 +73,17 @@ def run_human(pheno_vector,
 
     identifier = str(uuid.uuid4())
     
-    print("pheno_vector: ", pf(pheno_vector))
-    print("kinship_matrix: ", pf(kinship_matrix))
-    print("kinship_matrix.shape: ", pf(kinship_matrix.shape))
-
-    lmm_vars = pickle.dumps(dict(
-        pheno_vector = pheno_vector,
-        covariate_matrix = covariate_matrix,
-        kinship_matrix = kinship_matrix
-    ))
-    Redis.hset(identifier, "lmm_vars", lmm_vars)
-    Redis.expire(identifier, 60*60)
+    #print("pheno_vector: ", pf(pheno_vector))
+    #print("kinship_matrix: ", pf(kinship_matrix))
+    #print("kinship_matrix.shape: ", pf(kinship_matrix.shape))
+
+    #lmm_vars = pickle.dumps(dict(
+    #    pheno_vector = pheno_vector,
+    #    covariate_matrix = covariate_matrix,
+    #    kinship_matrix = kinship_matrix
+    #))
+    #Redis.hset(identifier, "lmm_vars", lmm_vars)
+    #Redis.expire(identifier, 60*60)
 
     if v.sum():
         pheno_vector = pheno_vector[keep]
@@ -136,13 +151,13 @@ def run_human(pheno_vector,
         #print("***** Added to {} queue *****".format(key))
         for snp, this_id in plink_input:
             #with Bench("part before association"):
-            #if count > 2000:
+            #if count > 1000:
             #    break
             count += 1
 
             percent_complete = (float(count) / total_snps) * 100
             #print("percent_complete: ", percent_complete)
-            loading_progress.store("percent_complete", percent_complete)
+            tempdata.store("percent_complete", percent_complete)
 
             #with Bench("actual association"):
             ps, ts = human_association(snp,
@@ -218,11 +233,17 @@ def human_association(snp,
     return ps, ts
 
 
-def run(pheno_vector,
+#def run(pheno_vector,
+#        genotype_matrix,
+#        restricted_max_likelihood=True,
+#        refit=False,
+#        temp_data=None):
+    
+def run_other(pheno_vector,
         genotype_matrix,
         restricted_max_likelihood=True,
         refit=False,
-        temp_data=None):
+        tempdata=None):
     """Takes the phenotype vector and genotype matrix and returns a set of p-values and t-statistics
     
     restricted_max_likelihood -- whether to use restricted max likelihood; True or False
@@ -232,8 +253,10 @@ def run(pheno_vector,
     
     """
     
+    
+    print("In run_other")
     with Bench("Calculate Kinship"):
-        kinship_matrix = calculate_kinship(genotype_matrix, temp_data)
+        kinship_matrix = calculate_kinship(genotype_matrix, tempdata)
     
     print("kinship_matrix: ", pf(kinship_matrix))
     print("kinship_matrix.shape: ", pf(kinship_matrix.shape))
@@ -252,9 +275,9 @@ def run(pheno_vector,
                                 kinship_matrix,
                                 restricted_max_likelihood=True,
                                 refit=False,
-                                temp_data=temp_data)
+                                temp_data=tempdata)
     Bench().report()
-    return t_stats, p_values
+    return p_values, t_stats
 
 
 def matrixMult(A,B):
@@ -677,3 +700,48 @@ class LMM:
        pl.xlabel("Heritability")
        pl.ylabel("Probability of data")
        pl.title(title)
+
+def main():
+    parser = argparse.ArgumentParser(description='Run pyLMM')
+    parser.add_argument('-k', '--key')
+    parser.add_argument('-s', '--species')
+    
+    opts = parser.parse_args()
+    
+    key = opts.key
+    species = opts.species
+    
+    json_params = Redis.get(key)
+    
+    params = json.loads(json_params)
+    print("params:", params)
+    
+    tempdata = temp_data.TempData(params['temp_uuid'])
+    if species == "human" :
+        ps, ts = run_human(pheno_vector = np.array(params['pheno_vector']),
+                  covariate_matrix = np.array(params['covariate_matrix']),
+                  plink_input_file = params['input_file_name'],
+                  kinship_matrix = np.array(params['kinship_matrix']),
+                  refit = params['refit'],
+                  tempdata = tempdata)
+    else:
+        ps, ts = run_other(pheno_vector = np.array(params['pheno_vector']),
+                  genotype_matrix = np.array(params['genotype_matrix']),
+                  restricted_max_likelihood = params['restricted_max_likelihood'],
+                  refit = params['refit'],
+                  tempdata = tempdata)
+        
+    results_key = "pylmm:results:" + params['temp_uuid']
+
+    json_results = json.dumps(dict(p_values = ps,
+                                   t_stats = ts))
+    
+    #Pushing json_results into a list where it is the only item because blpop needs a list
+    Redis.rpush(results_key, json_results)
+    Redis.expire(results_key, 60*60)
+
+if __name__ == '__main__':
+    main()
+
+
+
diff --git a/wqflask/wqflask/my_pylmm/run_pylmm.py b/wqflask/wqflask/my_pylmm/run_pylmm.py
new file mode 100644
index 00000000..0c96d986
--- /dev/null
+++ b/wqflask/wqflask/my_pylmm/run_pylmm.py
@@ -0,0 +1,77 @@
+from __future__ import absolute_import, print_function, division

+

+from base import data_set

+from base.species import TheSpecies

+    

+    def run(dataset_name, vals, temp_uuid):

+        """Generates p-values for each marker"""

+

+        tempdata = temp_data.TempData(temp_uuid)

+        

+        dataset = data_set.create_dataset(dataset_name)

+        species = TheSpecies(dataset=dataset)

+

+        samples = [] # Want only ones with values

+        vals = vals

+

+        for sample in dataset.group.samplelist:

+            samples.append(str(sample))

+            

+        gen_data(dataset, vals, tempdata)

+

+

+    def gen_data(dataset, vals)

+        dataset.group.get_markers()

+

+        pheno_vector = np.array([val == "x" and np.nan or float(val) for val in vals])

+

+        if dataset.group.species == "human":

+            p_values, t_stats = gen_human_results(pheno_vector, tempdata)

+        else:

+            genotype_data = [marker['genotypes'] for marker in dataset.group.markers.markers]

+            

+            no_val_samples = self.identify_empty_samples()

+            trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples)

+            

+            genotype_matrix = np.array(trimmed_genotype_data).T

+            

+            #print("pheno_vector: ", pf(pheno_vector))

+            #print("genotype_matrix: ", pf(genotype_matrix))

+            #print("genotype_matrix.shape: ", pf(genotype_matrix.shape))

+            

+            t_stats, p_values = lmm.run(

+                pheno_vector,

+                genotype_matrix,

+                restricted_max_likelihood=True,

+                refit=False,

+                temp_data=tempdata

+            )

+            #print("p_values:", p_values)

+        

+        self.dataset.group.markers.add_pvalues(p_values)

+        return self.dataset.group.markers.markers

+

+

+    def gen_human_results(self, pheno_vector, tempdata):

+        file_base = os.path.join(webqtlConfig.PYLMM_PATH, self.dataset.group.name)

+

+        plink_input = input.plink(file_base, type='b')

+        input_file_name = os.path.join(webqtlConfig.SNP_PATH, self.dataset.group.name + ".snps.gz")

+

+        pheno_vector = pheno_vector.reshape((len(pheno_vector), 1))

+        covariate_matrix = np.ones((pheno_vector.shape[0],1))

+        kinship_matrix = np.fromfile(open(file_base + '.kin','r'),sep=" ")

+        kinship_matrix.resize((len(plink_input.indivs),len(plink_input.indivs)))

+

+        p_values, t_stats = lmm.run_human(

+                pheno_vector,

+                covariate_matrix,

+                input_file_name,

+                kinship_matrix,

+                loading_progress=tempdata

+            )

+

+        return p_values, t_stats

+    

+if __name__ == '__main__':

+    run(dataset_name, vals, temp_uuid)
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/css/bar_chart.css b/wqflask/wqflask/static/new/css/bar_chart.css
index ba14fe4e..c8e081f9 100644
--- a/wqflask/wqflask/static/new/css/bar_chart.css
+++ b/wqflask/wqflask/static/new/css/bar_chart.css
@@ -7,6 +7,7 @@
 

 .bar {

   fill: steelblue;

+  shape-rendering: crispEdges;

 }

 

 .x.axis path {

diff --git a/wqflask/wqflask/static/new/css/marker_regression.css b/wqflask/wqflask/static/new/css/marker_regression.css
index a737c97e..56980026 100644
--- a/wqflask/wqflask/static/new/css/marker_regression.css
+++ b/wqflask/wqflask/static/new/css/marker_regression.css
@@ -15,10 +15,17 @@
     stroke: black;
     shape-rendering: crispEdges;
 }
+
 .manhattan_plot .x_axis text {
     text-anchor: end;
     font-family: sans-serif;
-    font-size: 8px;
+    font-size: 10px;
+}
+
+rect.pane {
+  cursor: move;
+  fill: none;
+  pointer-events: all;
 }
 
 /*rect {
diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.coffee b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
index e1bb36e1..3f12d956 100644
--- a/wqflask/wqflask/static/new/javascript/bar_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
@@ -129,89 +129,31 @@ class Bar_Chart
             #$('.x.axis').remove()
             #@add_x_axis(x_scale)
         )
-        
-        
-        
-        #d3.select(".update_bar_chart").on("click", =>
-        #    console.log("THIS IS:", $(this))
-        #    sort_by = $(this).val()
-        #    console.log("sort_by: ", sort_by)
-        #    if @attributes.length > 0
-        #        attribute = $("#color_attribute").val()
-        #    if sort_by = "value"
-        #        console.log("sorting by value")
-        #        sortItems = (a, b) ->
-        #            return a[1] - b[1]
-        #
-        #        @svg.selectAll(".bar")
-        #            .data(@sorted_samples())
-        #            .transition()
-        #            .duration(1000)
-        #            .attr("y", (d) =>
-        #
-        #                return @y_scale(d[1])
-        #            )
-        #            .attr("height", (d) =>
-        #                return @plot_height - @y_scale(d[1])
-        #            )
-        #            .style("fill", (d) =>
-        #                if @attributes.length > 0
-        #                    return @attr_color_dict[attribute][d[2][attribute]]
-        #                else
-        #                    return "steelblue"
-        #            )
-        #            .select("title")
-        #            .text((d) =>
-        #                return d[1]
-        #            )
-        #        sorted_sample_names = (sample[0] for sample in @sorted_samples())
-        #        x_scale = d3.scale.ordinal()
-        #            .domain(sorted_sample_names)
-        #            .rangeBands([0, @plot_width], .1)
-        #        $('.x.axis').remove()
-        #        @add_x_axis(x_scale)
-        #    else
-        #        console.log("sorting by name")
-        #        #$("#update_bar_chart").html('Sort By Value')
-        #        @svg.selectAll(".bar")
-        #            .data(@samples)
-        #            .transition()
-        #            .duration(1000)
-        #            .attr("y", (d) =>
-        #                return @y_scale(d[1])
-        #            )
-        #            .attr("height", (d) =>
-        #                return @plot_height - @y_scale(d[1])
-        #            )
-        #            .style("fill", (d) =>
-        #                if @attributes.length > 0
-        #                    return @attr_color_dict[attribute][d[2][attribute]]
-        #                else
-        #                    return "steelblue"
-        #            )
-        #            .select("title")
-        #            .text((d) =>
-        #                return d[1]
-        #            )
-        #        x_scale = d3.scale.ordinal()
-        #            .domain(@sample_names)
-        #            .rangeBands([0, @plot_width], .1)
-        #        $('.x.axis').remove()
-        #        @add_x_axis(x_scale)
-        #)
-        
+
         d3.select("#color_by_trait").on("click", =>
             @open_trait_selection()
-            
         )
 
-
     rebuild_bar_graph: (samples) ->
         console.log("samples:", samples)
         @svg.selectAll(".bar")
             .data(samples)
             .transition()
             .duration(1000)
+            .style("fill", (d) =>
+                if @attributes.length == 0 and @trait_color_dict?
+                    console.log("SAMPLE:", d[0])
+                    console.log("CHECKING:", @trait_color_dict[d[0]])
+                    #return "steelblue"
+                    return @trait_color_dict[d[0]]
+                else if @attributes.length > 0 and @attribute != "None"
+                    console.log("@attribute:", @attribute)
+                    console.log("d[2]", d[2])
+                    console.log("the_color:", @attr_color_dict[@attribute][d[2][@attribute]])
+                    return @attr_color_dict[@attribute][d[2][@attribute]]
+                else
+                    return "steelblue"
+            )
             .attr("y", (d) =>
                 return @y_scale(d[1])
             )
@@ -222,15 +164,10 @@ class Bar_Chart
             .text((d) =>
                 return d[1]
             )
-            .style("fill", (d) =>
-                if @attributes.length > 0 and @attribute != "None"
-                    console.log("@attribute:", @attribute)
-                    console.log("d[2]", d[2])
-                    console.log("the_color:", @attr_color_dict[@attribute][d[2][@attribute]])
-                    return @attr_color_dict[@attribute][d[2][@attribute]]
-                else
-                    return "steelblue"
-            )
+            #.style("fill", (d) =>
+            #    return @trait_color_dict[d[0]]
+            #    #return @attr_color_dict["collection_trait"][trimmed_samples[d[0]]]
+            #)
         sample_names = (sample[0] for sample in samples)
         console.log("sample_names2:", sample_names)
         x_scale = d3.scale.ordinal()
@@ -268,6 +205,35 @@ class Bar_Chart
                         #this_color_dict[value] = d3.rgb("lightblue").darker(color_range(parseInt(value)))
                         #this_color_dict[value] = "rgb(0, 0, " + color_range(parseInt(value)) + ")"
             @attr_color_dict[key] = this_color_dict
+            
+    get_trait_color_dict: (samples, vals) ->
+        @trait_color_dict = {}
+        console.log("vals:", vals)
+        for own key, distinct_vals of vals
+            this_color_dict = {}
+            if distinct_vals.length < 10
+                color = d3.scale.category10()
+                for value, i in distinct_vals
+                    this_color_dict[value] = color(i)
+            else
+                console.log("distinct_values:", distinct_vals)
+                #Check whether all values are numbers, and if they are get a corresponding
+                #color gradient
+                if _.every(distinct_vals, (d) =>
+                    if isNaN(d)
+                        return false
+                    else
+                        return true
+                )
+                    color_range = d3.scale.linear()
+                                    .domain([d3.min(distinct_vals),
+                                            d3.max(distinct_vals)])
+                                    .range([0,255])
+                    for value, i in distinct_vals
+                        console.log("color_range(value):", parseInt(color_range(value)))
+                        this_color_dict[value] = d3.rgb(parseInt(color_range(value)),0, 0)
+        for own sample, value of samples
+            @trait_color_dict[sample] = this_color_dict[value]
 
     convert_into_colors: (values) ->
         color_range = d3.scale.linear()
@@ -450,29 +416,38 @@ class Bar_Chart
         trimmed_samples = @trim_values(trait_sample_data)
         distinct_values = {}
         distinct_values["collection_trait"] = @get_distinct_values(trimmed_samples)
-        @get_attr_color_dict(distinct_values)
-        if $("#update_bar_chart").html() == 'Sort By Name' 
+        #@get_attr_color_dict(distinct_values)
+        @get_trait_color_dict(trimmed_samples, distinct_values)
+        console.log("TRAIT_COLOR_DICT:", @trait_color_dict)
+        console.log("SAMPLES:", @samples)
+        if @sort_by = "value"
             @svg.selectAll(".bar")
-                .data(@sorted_samples())
+                .data(@samples)
                 .transition()
                 .duration(1000)
                 .style("fill", (d) =>
-                    return @attr_color_dict["collection_trait"][trimmed_samples[d[0]]]
+                    console.log("this color:", @trait_color_dict[d[0]])
+                    return @trait_color_dict[d[0]]
                 )
                 .select("title")
                 .text((d) =>
                     return d[1]
-                )
+                )            
+
         else
             @svg.selectAll(".bar")
-                .data(@samples)
+                .data(@sorted_samples())
                 .transition()
                 .duration(1000)
                 .style("fill", (d) =>
-                    return @attr_color_dict["collection_trait"][trimmed_samples[d[0]]]
+                    console.log("this color:", @trait_color_dict[d[0]])
+                    return @trait_color_dict[d[0]]
                 )
-        
-    
+                .select("title")
+                .text((d) =>
+                    return d[1]
+                )            
+
     trim_values: (trait_sample_data) ->
         trimmed_samples = {}
         for sample in @sample_names
diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.js b/wqflask/wqflask/static/new/javascript/bar_chart.js
index b02ee1da..c0b056f8 100644
--- a/wqflask/wqflask/static/new/javascript/bar_chart.js
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.js
@@ -95,14 +95,12 @@
       var sample, sample_names, x_scale,
         _this = this;
       console.log("samples:", samples);
-      this.svg.selectAll(".bar").data(samples).transition().duration(1000).attr("y", function(d) {
-        return _this.y_scale(d[1]);
-      }).attr("height", function(d) {
-        return _this.plot_height - _this.y_scale(d[1]);
-      }).select("title").text(function(d) {
-        return d[1];
-      }).style("fill", function(d) {
-        if (_this.attributes.length > 0 && _this.attribute !== "None") {
+      this.svg.selectAll(".bar").data(samples).transition().duration(1000).style("fill", function(d) {
+        if (_this.attributes.length === 0 && (_this.trait_color_dict != null)) {
+          console.log("SAMPLE:", d[0]);
+          console.log("CHECKING:", _this.trait_color_dict[d[0]]);
+          return _this.trait_color_dict[d[0]];
+        } else if (_this.attributes.length > 0 && _this.attribute !== "None") {
           console.log("@attribute:", _this.attribute);
           console.log("d[2]", d[2]);
           console.log("the_color:", _this.attr_color_dict[_this.attribute][d[2][_this.attribute]]);
@@ -110,6 +108,12 @@
         } else {
           return "steelblue";
         }
+      }).attr("y", function(d) {
+        return _this.y_scale(d[1]);
+      }).attr("height", function(d) {
+        return _this.plot_height - _this.y_scale(d[1]);
+      }).select("title").text(function(d) {
+        return d[1];
       });
       sample_names = (function() {
         var _i, _len, _results;
@@ -164,6 +168,48 @@
       return _results;
     };
 
+    Bar_Chart.prototype.get_trait_color_dict = function(samples, vals) {
+      var color, color_range, distinct_vals, i, key, sample, this_color_dict, value, _i, _j, _len, _len1, _results,
+        _this = this;
+      this.trait_color_dict = {};
+      console.log("vals:", vals);
+      for (key in vals) {
+        if (!__hasProp.call(vals, key)) continue;
+        distinct_vals = vals[key];
+        this_color_dict = {};
+        if (distinct_vals.length < 10) {
+          color = d3.scale.category10();
+          for (i = _i = 0, _len = distinct_vals.length; _i < _len; i = ++_i) {
+            value = distinct_vals[i];
+            this_color_dict[value] = color(i);
+          }
+        } else {
+          console.log("distinct_values:", distinct_vals);
+          if (_.every(distinct_vals, function(d) {
+            if (isNaN(d)) {
+              return false;
+            } else {
+              return true;
+            }
+          })) {
+            color_range = d3.scale.linear().domain([d3.min(distinct_vals), d3.max(distinct_vals)]).range([0, 255]);
+            for (i = _j = 0, _len1 = distinct_vals.length; _j < _len1; i = ++_j) {
+              value = distinct_vals[i];
+              console.log("color_range(value):", parseInt(color_range(value)));
+              this_color_dict[value] = d3.rgb(parseInt(color_range(value)), 0, 0);
+            }
+          }
+        }
+      }
+      _results = [];
+      for (sample in samples) {
+        if (!__hasProp.call(samples, sample)) continue;
+        value = samples[sample];
+        _results.push(this.trait_color_dict[sample] = this_color_dict[value]);
+      }
+      return _results;
+    };
+
     Bar_Chart.prototype.convert_into_colors = function(values) {
       var color_range, i, value, _i, _len, _results;
       color_range = d3.scale.linear().domain([d3.min(values), d3.max(values)]).range([0, 255]);
@@ -346,16 +392,22 @@
       trimmed_samples = this.trim_values(trait_sample_data);
       distinct_values = {};
       distinct_values["collection_trait"] = this.get_distinct_values(trimmed_samples);
-      this.get_attr_color_dict(distinct_values);
-      if ($("#update_bar_chart").html() === 'Sort By Name') {
-        return this.svg.selectAll(".bar").data(this.sorted_samples()).transition().duration(1000).style("fill", function(d) {
-          return _this.attr_color_dict["collection_trait"][trimmed_samples[d[0]]];
+      this.get_trait_color_dict(trimmed_samples, distinct_values);
+      console.log("TRAIT_COLOR_DICT:", this.trait_color_dict);
+      console.log("SAMPLES:", this.samples);
+      if (this.sort_by = "value") {
+        return this.svg.selectAll(".bar").data(this.samples).transition().duration(1000).style("fill", function(d) {
+          console.log("this color:", _this.trait_color_dict[d[0]]);
+          return _this.trait_color_dict[d[0]];
         }).select("title").text(function(d) {
           return d[1];
         });
       } else {
-        return this.svg.selectAll(".bar").data(this.samples).transition().duration(1000).style("fill", function(d) {
-          return _this.attr_color_dict["collection_trait"][trimmed_samples[d[0]]];
+        return this.svg.selectAll(".bar").data(this.sorted_samples()).transition().duration(1000).style("fill", function(d) {
+          console.log("this color:", _this.trait_color_dict[d[0]]);
+          return _this.trait_color_dict[d[0]];
+        }).select("title").text(function(d) {
+          return d[1];
         });
       }
     };
diff --git a/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.coffee b/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.coffee
new file mode 100644
index 00000000..30e6ea5e
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.coffee
@@ -0,0 +1,211 @@
+root = exports ? this

+    

+class Chr_Manhattan_Plot

+    constructor: (@plot_height, @plot_width, @chr) ->

+        @qtl_results = js_data.qtl_results

+        console.log("qtl_results are:", @qtl_results)

+        console.log("chr is:", @chr)

+        

+        @get_max_chr()

+

+        @filter_qtl_results()

+        console.log("filtered results:", @these_results)

+        @get_qtl_count()

+

+        @x_coords = []

+        @y_coords = []

+        @marker_names = []

+

+        console.time('Create coordinates')

+        @create_coordinates()

+        console.log("@x_coords: ", @x_coords)

+        console.log("@y_coords: ", @y_coords)

+        console.timeEnd('Create coordinates')

+        

+        # Buffer to allow for the ticks/labels to be drawn

+        @x_buffer = @plot_width/30

+        @y_buffer = @plot_height/20

+        

+        @x_max = d3.max(@x_coords)

+        @y_max = d3.max(@y_coords) * 1.2

+    

+        @svg = @create_svg()

+

+        @plot_coordinates = _.zip(@x_coords, @y_coords, @marker_names)

+        console.log("coordinates:", @plot_coordinates)

+

+        @plot_height -= @y_buffer

+

+        @create_scales()

+

+        console.time('Create graph')

+        @create_graph()

+        console.timeEnd('Create graph')

+       

+    get_max_chr: () ->

+        @max_chr = 0

+        for key of js_data.chromosomes

+            console.log("key is:", key)

+            if parseInt(key) > @max_chr

+                @max_chr = parseInt(key)

+        

+    filter_qtl_results: () ->

+        @these_results = []

+        this_chr = 100

+        for result in @qtl_results

+            if result.chr == "X"

+                this_chr = @max_chr

+            else

+                this_chr = result.chr

+            console.log("this_chr is:", this_chr)

+            console.log("@chr[0] is:", parseInt(@chr[0]))

+            if this_chr > parseInt(@chr[0])

+                break

+            if parseInt(this_chr) == parseInt(@chr[0])

+                @these_results.push(result)

+

+    get_qtl_count: () ->

+        high_qtl_count = 0

+        for result in @these_results

+            if result.lod_score > 1

+                high_qtl_count += 1

+        console.log("high_qtl_count:", high_qtl_count)

+        

+        if high_qtl_count > 10000

+            @y_axis_filter = 2

+        else if high_qtl_count > 1000

+            @y_axis_filter = 1

+        else

+            @y_axis_filter = 0

+

+    create_coordinates: () ->

+        for result in @these_results

+            @x_coords.push(parseFloat(result.Mb))

+            @y_coords.push(result.lod_score)

+            @marker_names.push(result.name)

+            

+    create_svg: () ->

+        svg = d3.select("#manhattan_plot")

+            .append("svg")

+            .attr("class", "manhattan_plot")

+            .attr("width", @plot_width+@x_buffer)

+            .attr("height", @plot_height+@y_buffer)

+            .append("g")

+        return svg

+

+    create_scales: () ->

+        @x_scale = d3.scale.linear()

+            .domain([0, @chr[1]])

+            .range([@x_buffer, @plot_width])

+        @y_scale = d3.scale.linear()

+            .domain([@y_axis_filter, @y_max])

+            .range([@plot_height, @y_buffer])

+

+    create_graph: () ->

+        @add_border()

+        @add_x_axis()

+        @add_y_axis()

+        @add_plot_points()

+

+    add_border: () ->

+        border_coords = [[@y_buffer, @plot_height, @x_buffer, @x_buffer],

+                         [@y_buffer, @plot_height, @plot_width, @plot_width],

+                         [@y_buffer, @y_buffer, @x_buffer, @plot_width],

+                         [@plot_height, @plot_height, @x_buffer, @plot_width]]

+            

+        @svg.selectAll("line")

+            .data(border_coords)

+            .enter()

+            .append("line")

+            .attr("y1", (d) =>

+                return d[0]

+            )

+            .attr("y2", (d) =>

+                return d[1]

+            )

+            .attr("x1", (d) =>

+                return d[2]

+            )

+            .attr("x2", (d) =>

+                return d[3]

+            )             

+            .style("stroke", "#000")

+

+    add_x_axis: () ->

+        @xAxis = d3.svg.axis()

+                .scale(@x_scale)

+                .orient("bottom")

+                .ticks(20)

+

+        @xAxis.tickFormat((d) =>

+            d3.format("d") #format as integer

+            return (d)

+        )

+

+        @svg.append("g")

+            .attr("class", "x_axis")

+            .attr("transform", "translate(0," + @plot_height + ")")

+            .call(@xAxis)

+            .selectAll("text")

+                .attr("text-anchor", "right")

+                .attr("font-size", "12px")

+                .attr("dx", "-1.6em")

+                .attr("transform", (d) =>

+                    return "translate(-12,0) rotate(-90)"

+                )

+                

+    add_y_axis: () ->

+        @yAxis = d3.svg.axis()

+                .scale(@y_scale)

+                .orient("left")

+                .ticks(5)

+        

+        @svg.append("g")

+            .attr("class", "y_axis")

+            .attr("transform", "translate(" + @x_buffer + ",0)")

+            .call(@yAxis)

+            

+    add_plot_points: () ->

+        @plot_point = @svg.selectAll("circle")

+            .data(@plot_coordinates)

+            .enter()

+            .append("circle")

+            .attr("cx", (d) =>

+                return @x_scale(d[0])

+            )

+            .attr("cy", (d) =>

+                return @y_scale(d[1])

+            )

+            .attr("r", 2)

+            .attr("id", (d) =>

+                return "point_" + String(d[2])

+            )

+            .classed("circle", true)

+            .on("mouseover", (d) =>

+                console.log("d3.event is:", d3.event)

+                console.log("d is:", d)

+                this_id = "point_" + String(d[2])

+                d3.select("#" + this_id).classed("d3_highlight", true)

+                    .attr("r", 5)

+                    .attr("fill", "yellow")

+                    .call(@show_marker_in_table(d))

+            )

+            .on("mouseout", (d) =>

+                this_id = "point_" + String(d[2])

+                d3.select("#" + this_id).classed("d3_highlight", false)

+                    .attr("r", 2)

+                    .attr("fill", "black")

+                    #.call(@show_marker_in_table())

+            )

+

+    show_marker_in_table: (marker_info) ->

+        console.log("in show_marker_in_table")

+        ### Searches for the select marker in the results table below ###

+        if marker_info

+            marker_name = marker_info[2]

+            $("#qtl_results_filter").find("input:first").val(marker_name).change()

+        #else

+        #    marker_name = ""

+        #$("#qtl_results_filter").find("input:first").val(marker_name).change()

+

+root.Chr_Manhattan_Plot = Chr_Manhattan_Plot
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.js b/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.js
new file mode 100644
index 00000000..2cbab00c
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/chr_manhattan_plot.js
@@ -0,0 +1,206 @@
+// Generated by CoffeeScript 1.6.1
+(function() {
+  var Chr_Manhattan_Plot, root;
+
+  root = typeof exports !== "undefined" && exports !== null ? exports : this;
+
+  Chr_Manhattan_Plot = (function() {
+
+    function Chr_Manhattan_Plot(plot_height, plot_width, chr) {
+      this.plot_height = plot_height;
+      this.plot_width = plot_width;
+      this.chr = chr;
+      this.qtl_results = js_data.qtl_results;
+      console.log("qtl_results are:", this.qtl_results);
+      console.log("chr is:", this.chr);
+      this.get_max_chr();
+      this.filter_qtl_results();
+      console.log("filtered results:", this.these_results);
+      this.get_qtl_count();
+      this.x_coords = [];
+      this.y_coords = [];
+      this.marker_names = [];
+      console.time('Create coordinates');
+      this.create_coordinates();
+      console.log("@x_coords: ", this.x_coords);
+      console.log("@y_coords: ", this.y_coords);
+      console.timeEnd('Create coordinates');
+      this.x_buffer = this.plot_width / 30;
+      this.y_buffer = this.plot_height / 20;
+      this.x_max = d3.max(this.x_coords);
+      this.y_max = d3.max(this.y_coords) * 1.2;
+      this.svg = this.create_svg();
+      this.plot_coordinates = _.zip(this.x_coords, this.y_coords, this.marker_names);
+      console.log("coordinates:", this.plot_coordinates);
+      this.plot_height -= this.y_buffer;
+      this.create_scales();
+      console.time('Create graph');
+      this.create_graph();
+      console.timeEnd('Create graph');
+    }
+
+    Chr_Manhattan_Plot.prototype.get_max_chr = function() {
+      var key, _results;
+      this.max_chr = 0;
+      _results = [];
+      for (key in js_data.chromosomes) {
+        console.log("key is:", key);
+        if (parseInt(key) > this.max_chr) {
+          _results.push(this.max_chr = parseInt(key));
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    Chr_Manhattan_Plot.prototype.filter_qtl_results = function() {
+      var result, this_chr, _i, _len, _ref, _results;
+      this.these_results = [];
+      this_chr = 100;
+      _ref = this.qtl_results;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        if (result.chr === "X") {
+          this_chr = this.max_chr;
+        } else {
+          this_chr = result.chr;
+        }
+        console.log("this_chr is:", this_chr);
+        console.log("@chr[0] is:", parseInt(this.chr[0]));
+        if (this_chr > parseInt(this.chr[0])) {
+          break;
+        }
+        if (parseInt(this_chr) === parseInt(this.chr[0])) {
+          _results.push(this.these_results.push(result));
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    Chr_Manhattan_Plot.prototype.get_qtl_count = function() {
+      var high_qtl_count, result, _i, _len, _ref;
+      high_qtl_count = 0;
+      _ref = this.these_results;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        if (result.lod_score > 1) {
+          high_qtl_count += 1;
+        }
+      }
+      console.log("high_qtl_count:", high_qtl_count);
+      if (high_qtl_count > 10000) {
+        return this.y_axis_filter = 2;
+      } else if (high_qtl_count > 1000) {
+        return this.y_axis_filter = 1;
+      } else {
+        return this.y_axis_filter = 0;
+      }
+    };
+
+    Chr_Manhattan_Plot.prototype.create_coordinates = function() {
+      var result, _i, _len, _ref, _results;
+      _ref = this.these_results;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        this.x_coords.push(parseFloat(result.Mb));
+        this.y_coords.push(result.lod_score);
+        _results.push(this.marker_names.push(result.name));
+      }
+      return _results;
+    };
+
+    Chr_Manhattan_Plot.prototype.create_svg = function() {
+      var svg;
+      svg = d3.select("#manhattan_plot").append("svg").attr("class", "manhattan_plot").attr("width", this.plot_width + this.x_buffer).attr("height", this.plot_height + this.y_buffer).append("g");
+      return svg;
+    };
+
+    Chr_Manhattan_Plot.prototype.create_scales = function() {
+      this.x_scale = d3.scale.linear().domain([0, this.chr[1]]).range([this.x_buffer, this.plot_width]);
+      return this.y_scale = d3.scale.linear().domain([this.y_axis_filter, this.y_max]).range([this.plot_height, this.y_buffer]);
+    };
+
+    Chr_Manhattan_Plot.prototype.create_graph = function() {
+      this.add_border();
+      this.add_x_axis();
+      this.add_y_axis();
+      return this.add_plot_points();
+    };
+
+    Chr_Manhattan_Plot.prototype.add_border = function() {
+      var border_coords,
+        _this = this;
+      border_coords = [[this.y_buffer, this.plot_height, this.x_buffer, this.x_buffer], [this.y_buffer, this.plot_height, this.plot_width, this.plot_width], [this.y_buffer, this.y_buffer, this.x_buffer, this.plot_width], [this.plot_height, this.plot_height, this.x_buffer, this.plot_width]];
+      return this.svg.selectAll("line").data(border_coords).enter().append("line").attr("y1", function(d) {
+        return d[0];
+      }).attr("y2", function(d) {
+        return d[1];
+      }).attr("x1", function(d) {
+        return d[2];
+      }).attr("x2", function(d) {
+        return d[3];
+      }).style("stroke", "#000");
+    };
+
+    Chr_Manhattan_Plot.prototype.add_x_axis = function() {
+      var _this = this;
+      this.xAxis = d3.svg.axis().scale(this.x_scale).orient("bottom").ticks(20);
+      this.xAxis.tickFormat(function(d) {
+        d3.format("d");
+        return d;
+      });
+      return this.svg.append("g").attr("class", "x_axis").attr("transform", "translate(0," + this.plot_height + ")").call(this.xAxis).selectAll("text").attr("text-anchor", "right").attr("font-size", "12px").attr("dx", "-1.6em").attr("transform", function(d) {
+        return "translate(-12,0) rotate(-90)";
+      });
+    };
+
+    Chr_Manhattan_Plot.prototype.add_y_axis = function() {
+      this.yAxis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
+      return this.svg.append("g").attr("class", "y_axis").attr("transform", "translate(" + this.x_buffer + ",0)").call(this.yAxis);
+    };
+
+    Chr_Manhattan_Plot.prototype.add_plot_points = function() {
+      var _this = this;
+      return this.plot_point = this.svg.selectAll("circle").data(this.plot_coordinates).enter().append("circle").attr("cx", function(d) {
+        return _this.x_scale(d[0]);
+      }).attr("cy", function(d) {
+        return _this.y_scale(d[1]);
+      }).attr("r", 2).attr("id", function(d) {
+        return "point_" + String(d[2]);
+      }).classed("circle", true).on("mouseover", function(d) {
+        var this_id;
+        console.log("d3.event is:", d3.event);
+        console.log("d is:", d);
+        this_id = "point_" + String(d[2]);
+        return d3.select("#" + this_id).classed("d3_highlight", true).attr("r", 5).attr("fill", "yellow").call(_this.show_marker_in_table(d));
+      }).on("mouseout", function(d) {
+        var this_id;
+        this_id = "point_" + String(d[2]);
+        return d3.select("#" + this_id).classed("d3_highlight", false).attr("r", 2).attr("fill", "black");
+      });
+    };
+
+    Chr_Manhattan_Plot.prototype.show_marker_in_table = function(marker_info) {
+      var marker_name;
+      console.log("in show_marker_in_table");
+      /* Searches for the select marker in the results table below
+      */
+
+      if (marker_info) {
+        marker_name = marker_info[2];
+        return $("#qtl_results_filter").find("input:first").val(marker_name).change();
+      }
+    };
+
+    return Chr_Manhattan_Plot;
+
+  })();
+
+  root.Chr_Manhattan_Plot = Chr_Manhattan_Plot;
+
+}).call(this);
diff --git a/wqflask/wqflask/static/new/javascript/histogram.coffee b/wqflask/wqflask/static/new/javascript/histogram.coffee
new file mode 100644
index 00000000..97b833fd
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/histogram.coffee
@@ -0,0 +1,106 @@
+root = exports ? this

+

+class Histogram

+    constructor: (@sample_list, @sample_group) ->

+        @sort_by = "name"

+        @format_count = d3.format(",.0f") #a formatter for counts

+        @get_sample_vals()

+        

+        @margin = {top: 10, right: 30, bottom: 30, left: 30}

+        @plot_width = 960 - @margin.left - @margin.right

+        @plot_height = 500 - @margin.top - @margin.bottom

+

+        @x_buffer = @plot_width/20

+        @y_buffer = @plot_height/20

+

+        @y_min = d3.min(@sample_vals)  

+        @y_max = d3.max(@sample_vals) * 1.1

+        

+        @plot_height -= @y_buffer

+        @create_x_scale()

+        @get_histogram_data()

+        @create_y_scale()

+        

+        @svg = @create_svg()

+

+        @create_graph()

+

+    get_sample_vals: () ->

+        @sample_vals = (sample.value for sample in @sample_list when sample.value != null)

+

+    create_svg: () ->

+        svg = d3.select("#histogram")

+          .append("svg")

+            .attr("class", "bar_chart")

+            .attr("width", @plot_width + @margin.left + @margin.right)

+            .attr("height", @plot_height + @margin.top + @margin.bottom)

+          .append("g")

+            .attr("transform", "translate(" + @margin.left + "," + @margin.top + ")")

+

+        return svg

+

+    create_x_scale: () ->

+        console.log("min/max:", d3.min(@sample_vals) + "," + d3.max(@sample_vals))

+        @x_scale = d3.scale.linear()

+            .domain([d3.min(@sample_vals), d3.max(@sample_vals)])

+            .range([0, @plot_width]) 

+

+    get_histogram_data: () ->

+        console.log("sample_vals:", @sample_vals)

+        @histogram_data = d3.layout.histogram()

+            .bins(@x_scale.ticks(20))(@sample_vals)

+        console.log("histogram_data:", @histogram_data[0])

+

+    create_y_scale: () ->

+        @y_scale = d3.scale.linear()

+            .domain([0, d3.max(@histogram_data, (d) => return d.y )])

+            .range([@plot_height, 0])

+

+    create_graph: () ->

+        @add_x_axis()

+        @add_bars()

+

+    add_x_axis: () ->

+        x_axis = d3.svg.axis()

+            .scale(@x_scale)

+            .orient("bottom");

+        

+        @svg.append("g")

+            .attr("class", "x axis")

+            .attr("transform", "translate(0," + @plot_height + ")")

+            .call(x_axis)

+            

+    add_y_axis: () ->

+        y_axis = d3.svg.axis()

+                .scale(@y_scale)

+                .orient("left")

+                .ticks(5)

+                

+    add_bars: () ->

+        console.log("bar_width:", @x_scale(@histogram_data[0].dx))

+        bar = @svg.selectAll(".bar")

+            .data(@histogram_data)

+          .enter().append("g")

+            .attr("class", "bar")

+            .attr("transform", (d) =>

+                return "translate(" + @x_scale(d.x) + "," + @y_scale(d.y) + ")")

+        

+        bar.append("rect")

+            .attr("x", 1)

+            .attr("width", (@x_scale(@histogram_data[1].x) - @x_scale(@histogram_data[0].x)) - 1)

+            .attr("height", (d) =>

+                return @plot_height - @y_scale(d.y)

+            )

+        bar.append("text")

+            .attr("dy", ".75em")

+            .attr("y", 6)

+            .attr("x", (@x_scale(@histogram_data[1].x) - @x_scale(@histogram_data[0].x))/2)

+            .attr("text-anchor", "middle")

+            .style("fill", "#fff")

+            .text((d) =>

+                bar_height = @plot_height - @y_scale(d.y)

+                if bar_height > 20

+                    return @format_count(d.y)

+            )

+

+root.Histogram = Histogram
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/histogram.js b/wqflask/wqflask/static/new/javascript/histogram.js
new file mode 100644
index 00000000..eb00ca73
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/histogram.js
@@ -0,0 +1,118 @@
+// Generated by CoffeeScript 1.6.1
+(function() {
+  var Histogram, root;
+
+  root = typeof exports !== "undefined" && exports !== null ? exports : this;
+
+  Histogram = (function() {
+
+    function Histogram(sample_list, sample_group) {
+      this.sample_list = sample_list;
+      this.sample_group = sample_group;
+      this.sort_by = "name";
+      this.format_count = d3.format(",.0f");
+      this.get_sample_vals();
+      this.margin = {
+        top: 10,
+        right: 30,
+        bottom: 30,
+        left: 30
+      };
+      this.plot_width = 960 - this.margin.left - this.margin.right;
+      this.plot_height = 500 - this.margin.top - this.margin.bottom;
+      this.x_buffer = this.plot_width / 20;
+      this.y_buffer = this.plot_height / 20;
+      this.y_min = d3.min(this.sample_vals);
+      this.y_max = d3.max(this.sample_vals) * 1.1;
+      this.plot_height -= this.y_buffer;
+      this.create_x_scale();
+      this.get_histogram_data();
+      this.create_y_scale();
+      this.svg = this.create_svg();
+      this.create_graph();
+    }
+
+    Histogram.prototype.get_sample_vals = function() {
+      var sample;
+      return this.sample_vals = (function() {
+        var _i, _len, _ref, _results;
+        _ref = this.sample_list;
+        _results = [];
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          sample = _ref[_i];
+          if (sample.value !== null) {
+            _results.push(sample.value);
+          }
+        }
+        return _results;
+      }).call(this);
+    };
+
+    Histogram.prototype.create_svg = function() {
+      var svg;
+      svg = d3.select("#histogram").append("svg").attr("class", "bar_chart").attr("width", this.plot_width + this.margin.left + this.margin.right).attr("height", this.plot_height + this.margin.top + this.margin.bottom).append("g").attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
+      return svg;
+    };
+
+    Histogram.prototype.create_x_scale = function() {
+      console.log("min/max:", d3.min(this.sample_vals) + "," + d3.max(this.sample_vals));
+      return this.x_scale = d3.scale.linear().domain([d3.min(this.sample_vals), d3.max(this.sample_vals)]).range([0, this.plot_width]);
+    };
+
+    Histogram.prototype.get_histogram_data = function() {
+      console.log("sample_vals:", this.sample_vals);
+      this.histogram_data = d3.layout.histogram().bins(this.x_scale.ticks(20))(this.sample_vals);
+      return console.log("histogram_data:", this.histogram_data[0]);
+    };
+
+    Histogram.prototype.create_y_scale = function() {
+      var _this = this;
+      return this.y_scale = d3.scale.linear().domain([
+        0, d3.max(this.histogram_data, function(d) {
+          return d.y;
+        })
+      ]).range([this.plot_height, 0]);
+    };
+
+    Histogram.prototype.create_graph = function() {
+      this.add_x_axis();
+      return this.add_bars();
+    };
+
+    Histogram.prototype.add_x_axis = function() {
+      var x_axis;
+      x_axis = d3.svg.axis().scale(this.x_scale).orient("bottom");
+      return this.svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + this.plot_height + ")").call(x_axis);
+    };
+
+    Histogram.prototype.add_y_axis = function() {
+      var y_axis;
+      return y_axis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
+    };
+
+    Histogram.prototype.add_bars = function() {
+      var bar,
+        _this = this;
+      console.log("bar_width:", this.x_scale(this.histogram_data[0].dx));
+      bar = this.svg.selectAll(".bar").data(this.histogram_data).enter().append("g").attr("class", "bar").attr("transform", function(d) {
+        return "translate(" + _this.x_scale(d.x) + "," + _this.y_scale(d.y) + ")";
+      });
+      bar.append("rect").attr("x", 1).attr("width", (this.x_scale(this.histogram_data[1].x) - this.x_scale(this.histogram_data[0].x)) - 1).attr("height", function(d) {
+        return _this.plot_height - _this.y_scale(d.y);
+      });
+      return bar.append("text").attr("dy", ".75em").attr("y", 6).attr("x", (this.x_scale(this.histogram_data[1].x) - this.x_scale(this.histogram_data[0].x)) / 2).attr("text-anchor", "middle").style("fill", "#fff").text(function(d) {
+        var bar_height;
+        bar_height = _this.plot_height - _this.y_scale(d.y);
+        if (bar_height > 20) {
+          return _this.format_count(d.y);
+        }
+      });
+    };
+
+    return Histogram;
+
+  })();
+
+  root.Histogram = Histogram;
+
+}).call(this);
diff --git a/wqflask/wqflask/static/new/javascript/marker_regression.coffee b/wqflask/wqflask/static/new/javascript/marker_regression.coffee
index f5f13c27..3f8fbe0d 100644
--- a/wqflask/wqflask/static/new/javascript/marker_regression.coffee
+++ b/wqflask/wqflask/static/new/javascript/marker_regression.coffee
@@ -1,311 +1,443 @@
-$ ->
-    class Manhattan_Plot
-        constructor: (@plot_height, @plot_width) ->
-            @qtl_results = js_data.qtl_results
-            console.log("qtl_results are:", @qtl_results)
-            @chromosomes = js_data.chromosomes
+root = exports ? this
 
-            @total_length = 0
+class Manhattan_Plot
+    constructor: (@plot_height, @plot_width) ->
+        @qtl_results = js_data.qtl_results
+        console.log("qtl_results are:", @qtl_results)
+        @chromosomes = js_data.chromosomes
 
-            @max_chr = @get_max_chr()
+        @total_length = 0
 
-            @x_coords = []
-            @y_coords = []
-            @marker_names = []
-            console.time('Create coordinates')
-            @create_coordinates()
-            console.log("@x_coords: ", @x_coords)
-            console.log("@y_coords: ", @y_coords)
-            console.timeEnd('Create coordinates')
-            [@chr_lengths, @cumulative_chr_lengths] = @get_chr_lengths()
+        @max_chr = @get_max_chr()
 
-            # Buffer to allow for the ticks/labels to be drawn
-            @x_buffer = @plot_width/30
-            @y_buffer = @plot_height/20
-            
-            #@x_max = d3.max(@x_coords)
-            @x_max = @total_length
-            console.log("@x_max: ", @x_max)
-            console.log("@x_buffer: ", @x_buffer)
-            @y_max = d3.max(@y_coords) * 1.2
+        @x_coords = []
+        @y_coords = []
+        @marker_names = []
+        console.time('Create coordinates')
+        @get_qtl_count()
+        @create_coordinates()
+        console.log("@x_coords: ", @x_coords)
+        console.log("@y_coords: ", @y_coords)
+        console.timeEnd('Create coordinates')
+        [@chr_lengths, @cumulative_chr_lengths] = @get_chr_lengths()
 
-            @svg = @create_svg()
-            @plot_coordinates = _.zip(@x_coords, @y_coords, @marker_names)
-            
-            @plot_height -= @y_buffer
-            @create_scales()
-            console.time('Create graph')
-            @create_graph()
-            console.timeEnd('Create graph')
+        # Buffer to allow for the ticks/labels to be drawn
+        @x_buffer = @plot_width/30
+        @y_buffer = @plot_height/20
+        
+        #@x_max = d3.max(@x_coords)
+        @x_max = @total_length
+        console.log("@x_max: ", @x_max)
+        console.log("@x_buffer: ", @x_buffer)
+        @y_max = d3.max(@y_coords) * 1.2
 
-        get_max_chr: () ->
-            max_chr = 0
-            for result in @qtl_results
-                chr = parseInt(result.chr)
-                if not _.isNaN(chr) 
-                    if chr > max_chr
-                        max_chr = chr
-            return max_chr
+        @svg = @create_svg()
+        console.log("svg created")
 
-        get_chr_lengths: () ->
-            ###
-            #Gets a list of both individual and cumulative (the position of one on the graph
-            #is its own length plus the lengths of all preceding chromosomes) lengths in order
-            #to draw the vertical lines separating chromosomes and the chromosome labels
-            #
-            ###
-            
-            console.log("@chromosomes: ", @chromosomes)
-            
-            cumulative_chr_lengths = []
-            chr_lengths = []
-            total_length = 0
-            for key of @chromosomes
-                this_length = @chromosomes[key]
-                chr_lengths.push(this_length)
-                cumulative_chr_lengths.push(total_length + this_length)
-                total_length += this_length
+        @plot_coordinates = _.zip(@x_coords, @y_coords, @marker_names)
+        console.log("coordinates:", @plot_coordinates)
+        
+        @plot_height -= @y_buffer
 
-            console.log("chr_lengths: ", chr_lengths)
+        @create_scales()
 
-            return [chr_lengths, cumulative_chr_lengths]
+        console.time('Create graph')
+        @create_graph()
+        console.timeEnd('Create graph')
 
-        create_coordinates: () -> 
-            chr_lengths = []
-            chr_seen = []
-            for result in js_data.qtl_results
-                if result.chr == "X"
-                    chr_length = parseFloat(@chromosomes[20])
-                else
-                    chr_length = parseFloat(@chromosomes[result.chr])
-                if not(result.chr in chr_seen)
-                    chr_seen.push(result.chr) 
-                    chr_lengths.push(chr_length) 
-                    if result.chr != "1"
-                        @total_length += parseFloat(chr_lengths[chr_lengths.length - 2])
+    get_max_chr: () ->
+        max_chr = 0
+        for result in @qtl_results
+            chr = parseInt(result.chr)
+            if not _.isNaN(chr) 
+                if chr > max_chr
+                    max_chr = chr
+        return max_chr
+
+    get_chr_lengths: () ->
+        ###
+        #Gets a list of both individual and cumulative (the position of one on the graph
+        #is its own length plus the lengths of all preceding chromosomes) lengths in order
+        #to draw the vertical lines separating chromosomes and the chromosome labels
+        #
+        ###
+        
+        console.log("@chromosomes: ", @chromosomes)
+        
+        cumulative_chr_lengths = []
+        chr_lengths = []
+        total_length = 0
+        for key of @chromosomes
+            this_length = @chromosomes[key]
+            chr_lengths.push(this_length)
+            cumulative_chr_lengths.push(total_length + this_length)
+            total_length += this_length
+
+        console.log("chr_lengths: ", chr_lengths)
+
+        return [chr_lengths, cumulative_chr_lengths]
+
+    get_qtl_count: () ->
+        high_qtl_count = 0
+        for result in js_data.qtl_results
+            if result.lod_score > 1
+                high_qtl_count += 1
+        console.log("high_qtl_count:", high_qtl_count)
+        
+        if high_qtl_count > 10000
+            @y_axis_filter = 2
+        else if high_qtl_count > 1000
+            @y_axis_filter = 1
+        else
+            @y_axis_filter = 0
+
+            
+    create_coordinates: () -> 
+        chr_lengths = []
+        chr_seen = []
+        for result in js_data.qtl_results
+            if result.chr == "X"
+                chr_length = parseFloat(@chromosomes[20])
+            else
+                chr_length = parseFloat(@chromosomes[result.chr])
+            if not(result.chr in chr_seen)
+                chr_seen.push(result.chr) 
+                chr_lengths.push(chr_length)
+                console.log("result.chr:", result.chr)
+                console.log("total_length:", @total_length)
+                if parseInt(result.chr) != 1
+                    console.log("plus:", chr_lengths.length - 2)
+                    @total_length += parseFloat(chr_lengths[chr_lengths.length - 2])
+            if result.lod_score > @y_axis_filter
                 @x_coords.push(@total_length + parseFloat(result.Mb))
                 @y_coords.push(result.lod_score)
                 @marker_names.push(result.name)
-            @total_length += parseFloat(chr_lengths[chr_lengths.length-1])
-            #console.log("chr_lengths: ", chr_lengths)
+        @total_length += parseFloat(chr_lengths[chr_lengths.length-1])
 
-        show_marker_in_table: (marker_info) ->
-            console.log("in show_marker_in_table")
-            ### Searches for the select marker in the results table below ###
-            if marker_info
-                marker_name = marker_info[2]
-            else
-                marker_name = ""
-            $("#qtl_results_filter").find("input:first").val(marker_name).keypress()
+    show_marker_in_table: (marker_info) ->
+        console.log("in show_marker_in_table")
+        ### Searches for the select marker in the results table below ###
+        if marker_info
+            marker_name = marker_info[2]
+            $("#qtl_results_filter").find("input:first").val(marker_name).change()
+        #else
+        #    marker_name = ""
+        #$("#qtl_results_filter").find("input:first").val(marker_name).change()
 
-        create_svg: () ->
-            svg = d3.select("#manhattan_plots")
-                .append("svg")
-                .attr("class", "manhattan_plot")
-                .attr("width", @plot_width+@x_buffer)
-                .attr("height", @plot_height+@y_buffer)
-            
-            return svg
+    create_svg: () ->
+        svg = d3.select("#manhattan_plot")
+            .append("svg")
+            .attr("class", "manhattan_plot")
+            .attr("width", @plot_width+@x_buffer)
+            .attr("height", @plot_height+@y_buffer)
+            .append("g")
+            #.call(d3.behavior.zoom().x(@x_scale).y(@y_scale).scaleExtent([1,8]).on("zoom", () ->
+            #    @svg.selectAll("circle")
+            #        .attr("transform", transform)
+            #))
+        return svg
 
-        create_graph: () ->
-            @add_border()
-            @add_x_axis()
-            @add_y_axis()
-            @add_chr_lines()
-            @fill_chr_areas()
-            @add_chr_labels()
-            @add_plot_points()
+    #zoom: () ->
+    #    #@svg.selectAll.attr("transform", @transform)
+    #    @svg.selectAll("circle")
+    #        .attr("transform", transform)
+    #        
+    #transform: (d) ->
+    #    return "translate(" + @x_scale(d[0]) + "," + @y_scale(d[1]) + ")"
 
-        add_border: () ->
-            border_coords = [[@y_buffer, @plot_height, @x_buffer, @x_buffer],
-                             [@y_buffer, @plot_height, @plot_width, @plot_width],
-                             [@y_buffer, @y_buffer, @x_buffer, @plot_width],
-                             [@plot_height, @plot_height, @x_buffer, @plot_width]]
+    create_graph: () ->
+        @add_border()
+        @add_x_axis()
+        @add_y_axis()
+        @add_axis_labels()
+        @add_chr_lines()
+        #@fill_chr_areas()
+        @add_chr_labels()
+        @add_plot_points()
+        #@create_zoom_pane()
 
-            @svg.selectAll("line")
-                .data(border_coords)
-                .enter()
-                .append("line")
-                .attr("y1", (d) =>
-                    return d[0]
-                )
-                .attr("y2", (d) =>
-                    return d[1]
-                )
-                .attr("x1", (d) =>
-                    return d[2]
-                )
-                .attr("x2", (d) =>
-                    return d[3]
-                )             
-                .style("stroke", "#000")
+    add_border: () ->
+        border_coords = [[@y_buffer, @plot_height, @x_buffer, @x_buffer],
+                         [@y_buffer, @plot_height, @plot_width, @plot_width],
+                         [@y_buffer, @y_buffer, @x_buffer, @plot_width],
+                         [@plot_height, @plot_height, @x_buffer, @plot_width]]
 
-        create_scales: () ->
+        @svg.selectAll("line")
+            .data(border_coords)
+            .enter()
+            .append("line")
+            .attr("y1", (d) =>
+                return d[0]
+            )
+            .attr("y2", (d) =>
+                return d[1]
+            )
+            .attr("x1", (d) =>
+                return d[2]
+            )
+            .attr("x2", (d) =>
+                return d[3]
+            )             
+            .style("stroke", "#000")
+
+    create_scales: () ->
+        #@x_scale = d3.scale.linear()
+        #    .domain([0, d3.max(@x_coords)])
+        #    .range([@x_buffer, @plot_width])
+        if '24' of @chromosomes
+            console.log("@chromosomes[24]:", @chromosomes['24'])
+            console.log("@chromosomes[23]:", @chromosomes['23'])
+            console.log("@total_length:", @total_length)
+            console.log("d3.max(@xcoords):", d3.max(@x_coords))
             @x_scale = d3.scale.linear()
-                .domain([0, d3.max(@x_coords)])
+                .domain([0, (@total_length + @chromosomes['24'])])
                 .range([@x_buffer, @plot_width])
+        else
+            @x_scale = d3.scale.linear()
+                .domain([0, (@total_length + @chromosomes['20'])])
+                .range([@x_buffer, @plot_width])
+        @y_scale = d3.scale.linear()
+            .domain([@y_axis_filter, @y_max])
+            .range([@plot_height, @y_buffer])
 
-            @y_scale = d3.scale.linear()
-                .domain([0, @y_max])
-                .range([@plot_height, @y_buffer])
-
-        create_x_axis_tick_values: () ->
-            tick_vals = []
-            for val in [25..@cumulative_chr_lengths[0]] when val%25 == 0
-                tick_vals.push(val)
+    create_x_axis_tick_values: () ->
+        tick_vals = []
+        for val in [25..@cumulative_chr_lengths[0]] when val%25 == 0
+            tick_vals.push(val)
+            
+        for length, i in @cumulative_chr_lengths
+            if i == 0
+                continue
+            chr_ticks = []
+            tick_count = Math.floor(@chr_lengths[i]/25)
+            tick_val = parseInt(@cumulative_chr_lengths[i-1])
+            for tick in [0..(tick_count-1)]
+                tick_val += 25
+                chr_ticks.push(tick_val)
+            Array::push.apply tick_vals, chr_ticks    
                 
-            for length, i in @cumulative_chr_lengths
-                if i == 0
-                    continue
-                chr_ticks = []
-                tick_count = Math.floor(@chr_lengths[i]/25)
-                tick_val = parseInt(@cumulative_chr_lengths[i-1])
-                for tick in [0..(tick_count-1)]
-                    tick_val += 25
-                    chr_ticks.push(tick_val)
-                Array::push.apply tick_vals, chr_ticks    
-                    
-            #console.log("tick_vals:", tick_vals)
-            return tick_vals
+        #console.log("tick_vals:", tick_vals)
+        return tick_vals
 
-        add_x_axis: () ->
-            xAxis = d3.svg.axis()
-                    .scale(@x_scale)
-                    .orient("bottom")
-                    .tickValues(@create_x_axis_tick_values())
+    add_x_axis: () ->
+        @xAxis = d3.svg.axis()
+                .scale(@x_scale)
+                .orient("bottom")
+                .tickValues(@create_x_axis_tick_values())
 
-            next_chr = 1
-            tmp_tick_val = 0
-            xAxis.tickFormat((d) =>
-                d3.format("d") #format as integer
-                if d < @cumulative_chr_lengths[0]
-                    tick_val = d
+        next_chr = 1
+        tmp_tick_val = 0
+        @xAxis.tickFormat((d) =>
+            d3.format("d") #format as integer
+            if d < @cumulative_chr_lengths[0]
+                tick_val = d
+            else
+                next_chr_length = @cumulative_chr_lengths[next_chr]
+                if d > next_chr_length
+                    next_chr += 1
+                    tmp_tick_val = 25
+                    tick_val = tmp_tick_val
                 else
-                    next_chr_length = @cumulative_chr_lengths[next_chr]
-                    if d > next_chr_length
-                        next_chr += 1
-                        tmp_tick_val = 25
-                        tick_val = tmp_tick_val
-                    else
-                        tmp_tick_val += 25
-                        tick_val = tmp_tick_val
-                return (tick_val)
-            )
-
-            @svg.append("g")
-                .attr("class", "x_axis")
-                .attr("transform", "translate(0," + @plot_height + ")")
-                .call(xAxis)
-                .selectAll("text")
-                    .attr("text-anchor", "right")
-                    .attr("dx", "-1.6em")
-                    .attr("transform", (d) =>
-                        return "translate(-12,0) rotate(-90)"
-                    )
-                    #.attr("dy", "-1.0em")                        
-                                    
+                    tmp_tick_val += 25
+                    tick_val = tmp_tick_val
+            return (tick_val)
+        )
 
-        add_y_axis: () ->
-            yAxis = d3.svg.axis()
-                    .scale(@y_scale)
-                    .orient("left")
-                    .ticks(5)
+        @svg.append("g")
+            .attr("class", "x_axis")
+            .attr("transform", "translate(0," + @plot_height + ")")
+            .call(@xAxis)
+            .selectAll("text")
+                .attr("text-anchor", "right")
+                .attr("dx", "-1.6em")
+                .attr("transform", (d) =>
+                    return "translate(-12,0) rotate(-90)"
+                )
+                #.attr("dy", "-1.0em")                        
+                                
+ 
+    add_y_axis: () ->
+        @yAxis = d3.svg.axis()
+            .scale(@y_scale)
+            .orient("left")
+            .ticks(5)
+        
+        @svg.append("g")
+            .attr("class", "y_axis")
+            .attr("transform", "translate(" + @x_buffer + ",0)")
+            .call(@yAxis)
             
-            @svg.append("g")
-                .attr("class", "y_axis")
-                .attr("transform", "translate(" + @x_buffer + ",0)")
-                .call(yAxis)
+    add_axis_labels: () ->
+        @svg.append("text")
+            .attr("transform","rotate(-90)")
+            .attr("y", 0 - (@plot_height / 2))
+            .attr("x", @x_buffer)
+            .attr("dy", "1em")
+            .style("text-anchor", "middle")
+            .text("LOD Score")
 
-        add_chr_lines: () ->
-            @svg.selectAll("line")
-                .data(@cumulative_chr_lengths, (d) =>
-                    return d
-                )
-                .enter()
-                .append("line")
-                .attr("x1", @x_scale)
-                .attr("x2", @x_scale)
-                .attr("y1", @y_buffer)
-                .attr("y2", @plot_height)
-                .style("stroke", "#ccc")
-                
-        fill_chr_areas: () ->
-            @svg.selectAll("rect.chr_fill_area_1")
-                .data(_.zip(@chr_lengths, @cumulative_chr_lengths), (d) =>
-                    return d
-                )
-                .enter()
-                .append("rect")
-                .attr("class", "chr_fill_area_1")
-                .attr("x", (d, i) =>
-                    if i == 0
-                        return @x_scale(0)
-                    else
-                        return @x_scale(@cumulative_chr_lengths[i-1])
-                )
-                .attr("y", @y_buffer)
-                .attr("width", (d) =>
-                    return @x_scale(d[0])
-                )
-                .attr("height", @plot_height-@y_buffer)                
+    add_chr_lines: () ->
+        @svg.selectAll("line")
+            .data(@cumulative_chr_lengths, (d) =>
+                return d
+            )
+            .enter()
+            .append("line")
+            .attr("x1", @x_scale)
+            .attr("x2", @x_scale)
+            .attr("y1", @y_buffer)
+            .attr("y2", @plot_height)
+            .style("stroke", "#ccc")
+            
+            
+    fill_chr_areas: () ->
+        console.log("cumu_chr_lengths:", @cumulative_chr_lengths)
+        console.log("example:", @x_scale(@cumulative_chr_lengths[0]))
+        @svg.selectAll("rect.chr_fill_area")
+            .data(_.zip(@chr_lengths, @cumulative_chr_lengths), (d) =>
+                return d
+            )
+            .enter()
+            .append("rect")
+            .attr("x", (d) =>
+                if i == 0
+                    return @x_scale(0)
+                else
+                    return @x_scale(d[1])
+            )
+            .attr("y", @y_buffer)
+            .attr("width", (d) =>
+                return @x_scale(d[0])
+            )
+            .attr("height", @plot_height-@y_buffer)
+            #.attr("fill", (d, i) =>
+            #    if i%2
+            #        return "whitesmoke"
+            #    else
+            #        return "none"
+            #)
+            
+    fill_chr_areas2: () ->
+        console.log("cumu_chr_lengths:", @cumulative_chr_lengths)
+        console.log("example:", @x_scale(@cumulative_chr_lengths[0]))
+        @svg.selectAll("rect.chr_fill_area")
+            .data(_.zip(@chr_lengths, @cumulative_chr_lengths), (d) =>
+                return d
+            )
+            .enter()
+            .append("rect")
+            .attr("x", (d) =>
+                if i == 0
+                    return @x_scale(0)
+                else
+                    return @x_scale(d[1])
+            )
+            .attr("y", @y_buffer)
+            .attr("width", (d) =>
+                return @x_scale(d[0])
+            )
+            .attr("height", @plot_height-@y_buffer)
+            .attr("fill", (d, i) =>
+                return "whitesmoke"
+                #if i%2
+                #    return "whitesmoke"
+                #else
+                #    return "none"
+            )
 
-        add_chr_labels: () ->
-            chr_names = []
-            for key of @chromosomes
-                chr_names.push(key)
-            chr_info = _.zip(chr_names, @chr_lengths, @cumulative_chr_lengths)
-            @svg.selectAll("text")
-                .data(chr_info, (d) =>
-                    return d
-                )
-                .enter()
-                .append("text")
-                .text((d) =>
+    add_chr_labels: () ->
+        chr_names = []
+        for key of @chromosomes
+            chr_names.push(key)
+        chr_info = _.zip(chr_names, @chr_lengths, @cumulative_chr_lengths)
+        @svg.selectAll("text")
+            .data(chr_info, (d) =>
+                return d
+            )
+            .enter()
+            .append("text")
+            .attr("class", "chr_label")
+            .text((d) =>
+                if d[0] == "23"
+                    return "X"
+                else if d[0] == "24"
+                    return "X/Y"
+                else
                     return d[0]
-                )
-                .attr("x", (d) =>
-                    return @x_scale(d[2] - d[1]/2)
-                )
-                .attr("y", @plot_height * 0.1)
-                .attr("dx", "0em")
-                .attr("text-anchor", "middle")
-                .attr("font-family", "sans-serif")
-                .attr("font-size", "18px")
-                .attr("fill", "grey")
+            )
+            .attr("x", (d) =>
+                return @x_scale(d[2] - d[1]/2)
+            )
+            .attr("y", @plot_height * 0.1)
+            .attr("dx", "0em")
+            .attr("text-anchor", "middle")
+            .attr("font-family", "sans-serif")
+            .attr("font-size", "18px")
+            .attr("fill", "black")
+            .on("click", (d) =>
+                this_chr = d
+                @redraw_plot(d)
+            )
 
-        add_plot_points: () ->
-            @svg.selectAll("circle")
-                .data(@plot_coordinates)
-                .enter()
-                .append("circle")
-                .attr("cx", (d) =>
-                    return parseFloat(@x_buffer) + ((parseFloat(@plot_width)-parseFloat(@x_buffer)) * d[0]/parseFloat(@x_max))
-                )
-                .attr("cy", (d) =>
-                    return @plot_height - ((@plot_height-@y_buffer) * d[1]/@y_max)
-                )
-                .attr("r", 2)
-                .attr("id", (d) =>
-                    return "point_" + String(d[2])
-                )
-                .classed("circle", true)
-                .on("mouseover", (d) =>
-                    console.log("d3.event is:", d3.event)
-                    console.log("d is:", d)
-                    this_id = "point_" + String(d[2])
-                    d3.select("#" + this_id).classed("d3_highlight", true)
-                        .attr("r", 5)
-                        .attr("fill", "yellow")
-                        .call(@show_marker_in_table(d))
-                )
-                .on("mouseout", (d) =>
-                    this_id = "point_" + String(d[2])
-                    d3.select("#" + this_id).classed("d3_highlight", false)
-                        .attr("r", 2)
-                        .attr("fill", "black")
-                        .call(@show_marker_in_table())
-                )
+    add_plot_points: () ->
+        @plot_point = @svg.selectAll("circle")
+            .data(@plot_coordinates)
+            .enter()
+            .append("circle")
+            .attr("cx", (d) =>
+                return @x_scale(d[0])
+            )
+            .attr("cy", (d) =>
+                return @y_scale(d[1])
+            )
+            .attr("r", 2)
+            .attr("id", (d) =>
+                return "point_" + String(d[2])
+            )
+            .classed("circle", true)
+            .on("mouseover", (d) =>
+                console.log("d3.event is:", d3.event)
+                console.log("d is:", d)
+                this_id = "point_" + String(d[2])
+                d3.select("#" + this_id).classed("d3_highlight", true)
+                    .attr("r", 5)
+                    .attr("fill", "yellow")
+                    .call(@show_marker_in_table(d))
+            )
+            .on("mouseout", (d) =>
+                this_id = "point_" + String(d[2])
+                d3.select("#" + this_id).classed("d3_highlight", false)
+                    .attr("r", 2)
+                    .attr("fill", "black")
+            )
+            
+    redraw_plot: (chr_ob) ->
+        console.log("chr_name is:", chr_ob[0])
+        console.log("chr_length is:", chr_ob[1])
+        $('#manhattan_plot').remove()
+        $('#manhattan_plot_container').append('<div id="manhattan_plot"></div>')
+        root.chr_plot = new Chr_Manhattan_Plot(600, 1200, chr_ob)
+        
+
+    create_zoom_pane: () ->
+        zoom = d3.behavior.zoom()
+            .on("zoom", draw);
+            
+        @svg.append("rect")
+            .attr("class", "pane")
+            .attr("width", @plot_width)
+            .attr("height", @plot_height)
+            .call(zoom)
+    
+    draw: () ->
+      @svg.select("g.x_axis").call(@xAxis);
+      @svg.select("g.y_axis").call(@yAxis);
+      @svg.select("path.area").attr("d", area);
+      @svg.select("path.line").attr("d", line);
+    
 
-    console.time('Create manhattan plot')
-    new Manhattan_Plot(600, 1200)
-    console.timeEnd('Create manhattan plot')
\ No newline at end of file
+    #console.time('Create manhattan plot')
+    #new Manhattan_Plot(600, 1200)
+    #console.timeEnd('Create manhattan plot')
+    
+root.Manhattan_Plot = new Manhattan_Plot(600, 1200)
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/marker_regression.js b/wqflask/wqflask/static/new/javascript/marker_regression.js
index cdf37671..86509316 100644
--- a/wqflask/wqflask/static/new/javascript/marker_regression.js
+++ b/wqflask/wqflask/static/new/javascript/marker_regression.js
@@ -1,286 +1,374 @@
 // Generated by CoffeeScript 1.6.1
 (function() {
-  var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+  var Manhattan_Plot, root,
+    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
 
-  $(function() {
-    var Manhattan_Plot;
-    Manhattan_Plot = (function() {
+  root = typeof exports !== "undefined" && exports !== null ? exports : this;
 
-      function Manhattan_Plot(plot_height, plot_width) {
-        var _ref;
-        this.plot_height = plot_height;
-        this.plot_width = plot_width;
-        this.qtl_results = js_data.qtl_results;
-        console.log("qtl_results are:", this.qtl_results);
-        this.chromosomes = js_data.chromosomes;
-        this.total_length = 0;
-        this.max_chr = this.get_max_chr();
-        this.x_coords = [];
-        this.y_coords = [];
-        this.marker_names = [];
-        console.time('Create coordinates');
-        this.create_coordinates();
-        console.log("@x_coords: ", this.x_coords);
-        console.log("@y_coords: ", this.y_coords);
-        console.timeEnd('Create coordinates');
-        _ref = this.get_chr_lengths(), this.chr_lengths = _ref[0], this.cumulative_chr_lengths = _ref[1];
-        this.x_buffer = this.plot_width / 30;
-        this.y_buffer = this.plot_height / 20;
-        this.x_max = this.total_length;
-        console.log("@x_max: ", this.x_max);
-        console.log("@x_buffer: ", this.x_buffer);
-        this.y_max = d3.max(this.y_coords) * 1.2;
-        this.svg = this.create_svg();
-        this.plot_coordinates = _.zip(this.x_coords, this.y_coords, this.marker_names);
-        this.plot_height -= this.y_buffer;
-        this.create_scales();
-        console.time('Create graph');
-        this.create_graph();
-        console.timeEnd('Create graph');
-      }
+  Manhattan_Plot = (function() {
+
+    function Manhattan_Plot(plot_height, plot_width) {
+      var _ref;
+      this.plot_height = plot_height;
+      this.plot_width = plot_width;
+      this.qtl_results = js_data.qtl_results;
+      console.log("qtl_results are:", this.qtl_results);
+      this.chromosomes = js_data.chromosomes;
+      this.total_length = 0;
+      this.max_chr = this.get_max_chr();
+      this.x_coords = [];
+      this.y_coords = [];
+      this.marker_names = [];
+      console.time('Create coordinates');
+      this.get_qtl_count();
+      this.create_coordinates();
+      console.log("@x_coords: ", this.x_coords);
+      console.log("@y_coords: ", this.y_coords);
+      console.timeEnd('Create coordinates');
+      _ref = this.get_chr_lengths(), this.chr_lengths = _ref[0], this.cumulative_chr_lengths = _ref[1];
+      this.x_buffer = this.plot_width / 30;
+      this.y_buffer = this.plot_height / 20;
+      this.x_max = this.total_length;
+      console.log("@x_max: ", this.x_max);
+      console.log("@x_buffer: ", this.x_buffer);
+      this.y_max = d3.max(this.y_coords) * 1.2;
+      this.svg = this.create_svg();
+      console.log("svg created");
+      this.plot_coordinates = _.zip(this.x_coords, this.y_coords, this.marker_names);
+      console.log("coordinates:", this.plot_coordinates);
+      this.plot_height -= this.y_buffer;
+      this.create_scales();
+      console.time('Create graph');
+      this.create_graph();
+      console.timeEnd('Create graph');
+    }
 
-      Manhattan_Plot.prototype.get_max_chr = function() {
-        var chr, max_chr, result, _i, _len, _ref;
-        max_chr = 0;
-        _ref = this.qtl_results;
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          result = _ref[_i];
-          chr = parseInt(result.chr);
-          if (!_.isNaN(chr)) {
-            if (chr > max_chr) {
-              max_chr = chr;
-            }
+    Manhattan_Plot.prototype.get_max_chr = function() {
+      var chr, max_chr, result, _i, _len, _ref;
+      max_chr = 0;
+      _ref = this.qtl_results;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        chr = parseInt(result.chr);
+        if (!_.isNaN(chr)) {
+          if (chr > max_chr) {
+            max_chr = chr;
           }
         }
-        return max_chr;
-      };
+      }
+      return max_chr;
+    };
 
-      Manhattan_Plot.prototype.get_chr_lengths = function() {
-        /*
-        #Gets a list of both individual and cumulative (the position of one on the graph
-        #is its own length plus the lengths of all preceding chromosomes) lengths in order
-        #to draw the vertical lines separating chromosomes and the chromosome labels
-        #
-        */
+    Manhattan_Plot.prototype.get_chr_lengths = function() {
+      /*
+      #Gets a list of both individual and cumulative (the position of one on the graph
+      #is its own length plus the lengths of all preceding chromosomes) lengths in order
+      #to draw the vertical lines separating chromosomes and the chromosome labels
+      #
+      */
+
+      var chr_lengths, cumulative_chr_lengths, key, this_length, total_length;
+      console.log("@chromosomes: ", this.chromosomes);
+      cumulative_chr_lengths = [];
+      chr_lengths = [];
+      total_length = 0;
+      for (key in this.chromosomes) {
+        this_length = this.chromosomes[key];
+        chr_lengths.push(this_length);
+        cumulative_chr_lengths.push(total_length + this_length);
+        total_length += this_length;
+      }
+      console.log("chr_lengths: ", chr_lengths);
+      return [chr_lengths, cumulative_chr_lengths];
+    };
 
-        var chr_lengths, cumulative_chr_lengths, key, this_length, total_length;
-        console.log("@chromosomes: ", this.chromosomes);
-        cumulative_chr_lengths = [];
-        chr_lengths = [];
-        total_length = 0;
-        for (key in this.chromosomes) {
-          this_length = this.chromosomes[key];
-          chr_lengths.push(this_length);
-          cumulative_chr_lengths.push(total_length + this_length);
-          total_length += this_length;
+    Manhattan_Plot.prototype.get_qtl_count = function() {
+      var high_qtl_count, result, _i, _len, _ref;
+      high_qtl_count = 0;
+      _ref = js_data.qtl_results;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        if (result.lod_score > 1) {
+          high_qtl_count += 1;
         }
-        console.log("chr_lengths: ", chr_lengths);
-        return [chr_lengths, cumulative_chr_lengths];
-      };
+      }
+      console.log("high_qtl_count:", high_qtl_count);
+      if (high_qtl_count > 10000) {
+        return this.y_axis_filter = 2;
+      } else if (high_qtl_count > 1000) {
+        return this.y_axis_filter = 1;
+      } else {
+        return this.y_axis_filter = 0;
+      }
+    };
 
-      Manhattan_Plot.prototype.create_coordinates = function() {
-        var chr_length, chr_lengths, chr_seen, result, _i, _len, _ref, _ref1;
-        chr_lengths = [];
-        chr_seen = [];
-        _ref = js_data.qtl_results;
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          result = _ref[_i];
-          if (result.chr === "X") {
-            chr_length = parseFloat(this.chromosomes[20]);
-          } else {
-            chr_length = parseFloat(this.chromosomes[result.chr]);
-          }
-          if (!(_ref1 = result.chr, __indexOf.call(chr_seen, _ref1) >= 0)) {
-            chr_seen.push(result.chr);
-            chr_lengths.push(chr_length);
-            if (result.chr !== "1") {
-              this.total_length += parseFloat(chr_lengths[chr_lengths.length - 2]);
-            }
+    Manhattan_Plot.prototype.create_coordinates = function() {
+      var chr_length, chr_lengths, chr_seen, result, _i, _len, _ref, _ref1;
+      chr_lengths = [];
+      chr_seen = [];
+      _ref = js_data.qtl_results;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        if (result.chr === "X") {
+          chr_length = parseFloat(this.chromosomes[20]);
+        } else {
+          chr_length = parseFloat(this.chromosomes[result.chr]);
+        }
+        if (!(_ref1 = result.chr, __indexOf.call(chr_seen, _ref1) >= 0)) {
+          chr_seen.push(result.chr);
+          chr_lengths.push(chr_length);
+          console.log("result.chr:", result.chr);
+          console.log("total_length:", this.total_length);
+          if (parseInt(result.chr) !== 1) {
+            console.log("plus:", chr_lengths.length - 2);
+            this.total_length += parseFloat(chr_lengths[chr_lengths.length - 2]);
           }
+        }
+        if (result.lod_score > this.y_axis_filter) {
           this.x_coords.push(this.total_length + parseFloat(result.Mb));
           this.y_coords.push(result.lod_score);
           this.marker_names.push(result.name);
         }
-        return this.total_length += parseFloat(chr_lengths[chr_lengths.length - 1]);
-      };
+      }
+      return this.total_length += parseFloat(chr_lengths[chr_lengths.length - 1]);
+    };
 
-      Manhattan_Plot.prototype.show_marker_in_table = function(marker_info) {
-        var marker_name;
-        console.log("in show_marker_in_table");
-        /* Searches for the select marker in the results table below
-        */
+    Manhattan_Plot.prototype.show_marker_in_table = function(marker_info) {
+      var marker_name;
+      console.log("in show_marker_in_table");
+      /* Searches for the select marker in the results table below
+      */
 
-        if (marker_info) {
-          marker_name = marker_info[2];
-        } else {
-          marker_name = "";
-        }
-        return $("#qtl_results_filter").find("input:first").val(marker_name).keypress();
-      };
+      if (marker_info) {
+        marker_name = marker_info[2];
+        return $("#qtl_results_filter").find("input:first").val(marker_name).change();
+      }
+    };
 
-      Manhattan_Plot.prototype.create_svg = function() {
-        var svg;
-        svg = d3.select("#manhattan_plots").append("svg").attr("class", "manhattan_plot").attr("width", this.plot_width + this.x_buffer).attr("height", this.plot_height + this.y_buffer);
-        return svg;
-      };
+    Manhattan_Plot.prototype.create_svg = function() {
+      var svg;
+      svg = d3.select("#manhattan_plot").append("svg").attr("class", "manhattan_plot").attr("width", this.plot_width + this.x_buffer).attr("height", this.plot_height + this.y_buffer).append("g");
+      return svg;
+    };
 
-      Manhattan_Plot.prototype.create_graph = function() {
-        this.add_border();
-        this.add_x_axis();
-        this.add_y_axis();
-        this.add_chr_lines();
-        this.fill_chr_areas();
-        this.add_chr_labels();
-        return this.add_plot_points();
-      };
+    Manhattan_Plot.prototype.create_graph = function() {
+      this.add_border();
+      this.add_x_axis();
+      this.add_y_axis();
+      this.add_axis_labels();
+      this.add_chr_lines();
+      this.add_chr_labels();
+      return this.add_plot_points();
+    };
 
-      Manhattan_Plot.prototype.add_border = function() {
-        var border_coords,
-          _this = this;
-        border_coords = [[this.y_buffer, this.plot_height, this.x_buffer, this.x_buffer], [this.y_buffer, this.plot_height, this.plot_width, this.plot_width], [this.y_buffer, this.y_buffer, this.x_buffer, this.plot_width], [this.plot_height, this.plot_height, this.x_buffer, this.plot_width]];
-        return this.svg.selectAll("line").data(border_coords).enter().append("line").attr("y1", function(d) {
-          return d[0];
-        }).attr("y2", function(d) {
-          return d[1];
-        }).attr("x1", function(d) {
-          return d[2];
-        }).attr("x2", function(d) {
-          return d[3];
-        }).style("stroke", "#000");
-      };
+    Manhattan_Plot.prototype.add_border = function() {
+      var border_coords,
+        _this = this;
+      border_coords = [[this.y_buffer, this.plot_height, this.x_buffer, this.x_buffer], [this.y_buffer, this.plot_height, this.plot_width, this.plot_width], [this.y_buffer, this.y_buffer, this.x_buffer, this.plot_width], [this.plot_height, this.plot_height, this.x_buffer, this.plot_width]];
+      return this.svg.selectAll("line").data(border_coords).enter().append("line").attr("y1", function(d) {
+        return d[0];
+      }).attr("y2", function(d) {
+        return d[1];
+      }).attr("x1", function(d) {
+        return d[2];
+      }).attr("x2", function(d) {
+        return d[3];
+      }).style("stroke", "#000");
+    };
 
-      Manhattan_Plot.prototype.create_scales = function() {
-        this.x_scale = d3.scale.linear().domain([0, d3.max(this.x_coords)]).range([this.x_buffer, this.plot_width]);
-        return this.y_scale = d3.scale.linear().domain([0, this.y_max]).range([this.plot_height, this.y_buffer]);
-      };
+    Manhattan_Plot.prototype.create_scales = function() {
+      if ('24' in this.chromosomes) {
+        console.log("@chromosomes[24]:", this.chromosomes['24']);
+        console.log("@chromosomes[23]:", this.chromosomes['23']);
+        console.log("@total_length:", this.total_length);
+        console.log("d3.max(@xcoords):", d3.max(this.x_coords));
+        this.x_scale = d3.scale.linear().domain([0, this.total_length + this.chromosomes['24']]).range([this.x_buffer, this.plot_width]);
+      } else {
+        this.x_scale = d3.scale.linear().domain([0, this.total_length + this.chromosomes['20']]).range([this.x_buffer, this.plot_width]);
+      }
+      return this.y_scale = d3.scale.linear().domain([this.y_axis_filter, this.y_max]).range([this.plot_height, this.y_buffer]);
+    };
 
-      Manhattan_Plot.prototype.create_x_axis_tick_values = function() {
-        var chr_ticks, i, length, tick, tick_count, tick_val, tick_vals, val, _i, _j, _k, _len, _ref, _ref1, _ref2;
-        tick_vals = [];
-        for (val = _i = 25, _ref = this.cumulative_chr_lengths[0]; 25 <= _ref ? _i <= _ref : _i >= _ref; val = 25 <= _ref ? ++_i : --_i) {
-          if (val % 25 === 0) {
-            tick_vals.push(val);
-          }
+    Manhattan_Plot.prototype.create_x_axis_tick_values = function() {
+      var chr_ticks, i, length, tick, tick_count, tick_val, tick_vals, val, _i, _j, _k, _len, _ref, _ref1, _ref2;
+      tick_vals = [];
+      for (val = _i = 25, _ref = this.cumulative_chr_lengths[0]; 25 <= _ref ? _i <= _ref : _i >= _ref; val = 25 <= _ref ? ++_i : --_i) {
+        if (val % 25 === 0) {
+          tick_vals.push(val);
         }
-        _ref1 = this.cumulative_chr_lengths;
-        for (i = _j = 0, _len = _ref1.length; _j < _len; i = ++_j) {
-          length = _ref1[i];
-          if (i === 0) {
-            continue;
-          }
-          chr_ticks = [];
-          tick_count = Math.floor(this.chr_lengths[i] / 25);
-          tick_val = parseInt(this.cumulative_chr_lengths[i - 1]);
-          for (tick = _k = 0, _ref2 = tick_count - 1; 0 <= _ref2 ? _k <= _ref2 : _k >= _ref2; tick = 0 <= _ref2 ? ++_k : --_k) {
-            tick_val += 25;
-            chr_ticks.push(tick_val);
-          }
-          Array.prototype.push.apply(tick_vals, chr_ticks);
+      }
+      _ref1 = this.cumulative_chr_lengths;
+      for (i = _j = 0, _len = _ref1.length; _j < _len; i = ++_j) {
+        length = _ref1[i];
+        if (i === 0) {
+          continue;
+        }
+        chr_ticks = [];
+        tick_count = Math.floor(this.chr_lengths[i] / 25);
+        tick_val = parseInt(this.cumulative_chr_lengths[i - 1]);
+        for (tick = _k = 0, _ref2 = tick_count - 1; 0 <= _ref2 ? _k <= _ref2 : _k >= _ref2; tick = 0 <= _ref2 ? ++_k : --_k) {
+          tick_val += 25;
+          chr_ticks.push(tick_val);
         }
-        return tick_vals;
-      };
+        Array.prototype.push.apply(tick_vals, chr_ticks);
+      }
+      return tick_vals;
+    };
 
-      Manhattan_Plot.prototype.add_x_axis = function() {
-        var next_chr, tmp_tick_val, xAxis,
-          _this = this;
-        xAxis = d3.svg.axis().scale(this.x_scale).orient("bottom").tickValues(this.create_x_axis_tick_values());
-        next_chr = 1;
-        tmp_tick_val = 0;
-        xAxis.tickFormat(function(d) {
-          var next_chr_length, tick_val;
-          d3.format("d");
-          if (d < _this.cumulative_chr_lengths[0]) {
-            tick_val = d;
+    Manhattan_Plot.prototype.add_x_axis = function() {
+      var next_chr, tmp_tick_val,
+        _this = this;
+      this.xAxis = d3.svg.axis().scale(this.x_scale).orient("bottom").tickValues(this.create_x_axis_tick_values());
+      next_chr = 1;
+      tmp_tick_val = 0;
+      this.xAxis.tickFormat(function(d) {
+        var next_chr_length, tick_val;
+        d3.format("d");
+        if (d < _this.cumulative_chr_lengths[0]) {
+          tick_val = d;
+        } else {
+          next_chr_length = _this.cumulative_chr_lengths[next_chr];
+          if (d > next_chr_length) {
+            next_chr += 1;
+            tmp_tick_val = 25;
+            tick_val = tmp_tick_val;
           } else {
-            next_chr_length = _this.cumulative_chr_lengths[next_chr];
-            if (d > next_chr_length) {
-              next_chr += 1;
-              tmp_tick_val = 25;
-              tick_val = tmp_tick_val;
-            } else {
-              tmp_tick_val += 25;
-              tick_val = tmp_tick_val;
-            }
+            tmp_tick_val += 25;
+            tick_val = tmp_tick_val;
           }
-          return tick_val;
-        });
-        return this.svg.append("g").attr("class", "x_axis").attr("transform", "translate(0," + this.plot_height + ")").call(xAxis).selectAll("text").attr("text-anchor", "right").attr("dx", "-1.6em").attr("transform", function(d) {
-          return "translate(-12,0) rotate(-90)";
-        });
-      };
+        }
+        return tick_val;
+      });
+      return this.svg.append("g").attr("class", "x_axis").attr("transform", "translate(0," + this.plot_height + ")").call(this.xAxis).selectAll("text").attr("text-anchor", "right").attr("dx", "-1.6em").attr("transform", function(d) {
+        return "translate(-12,0) rotate(-90)";
+      });
+    };
 
-      Manhattan_Plot.prototype.add_y_axis = function() {
-        var yAxis;
-        yAxis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
-        return this.svg.append("g").attr("class", "y_axis").attr("transform", "translate(" + this.x_buffer + ",0)").call(yAxis);
-      };
+    Manhattan_Plot.prototype.add_y_axis = function() {
+      this.yAxis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
+      return this.svg.append("g").attr("class", "y_axis").attr("transform", "translate(" + this.x_buffer + ",0)").call(this.yAxis);
+    };
 
-      Manhattan_Plot.prototype.add_chr_lines = function() {
-        var _this = this;
-        return this.svg.selectAll("line").data(this.cumulative_chr_lengths, function(d) {
-          return d;
-        }).enter().append("line").attr("x1", this.x_scale).attr("x2", this.x_scale).attr("y1", this.y_buffer).attr("y2", this.plot_height).style("stroke", "#ccc");
-      };
+    Manhattan_Plot.prototype.add_axis_labels = function() {
+      return this.svg.append("text").attr("transform", "rotate(-90)").attr("y", 0 - (this.plot_height / 2)).attr("x", this.x_buffer).attr("dy", "1em").style("text-anchor", "middle").text("LOD Score");
+    };
 
-      Manhattan_Plot.prototype.fill_chr_areas = function() {
-        var _this = this;
-        return this.svg.selectAll("rect.chr_fill_area_1").data(_.zip(this.chr_lengths, this.cumulative_chr_lengths), function(d) {
-          return d;
-        }).enter().append("rect").attr("class", "chr_fill_area_1").attr("x", function(d, i) {
-          if (i === 0) {
-            return _this.x_scale(0);
-          } else {
-            return _this.x_scale(_this.cumulative_chr_lengths[i - 1]);
-          }
-        }).attr("y", this.y_buffer).attr("width", function(d) {
-          return _this.x_scale(d[0]);
-        }).attr("height", this.plot_height - this.y_buffer);
-      };
+    Manhattan_Plot.prototype.add_chr_lines = function() {
+      var _this = this;
+      return this.svg.selectAll("line").data(this.cumulative_chr_lengths, function(d) {
+        return d;
+      }).enter().append("line").attr("x1", this.x_scale).attr("x2", this.x_scale).attr("y1", this.y_buffer).attr("y2", this.plot_height).style("stroke", "#ccc");
+    };
+
+    Manhattan_Plot.prototype.fill_chr_areas = function() {
+      var _this = this;
+      console.log("cumu_chr_lengths:", this.cumulative_chr_lengths);
+      console.log("example:", this.x_scale(this.cumulative_chr_lengths[0]));
+      return this.svg.selectAll("rect.chr_fill_area").data(_.zip(this.chr_lengths, this.cumulative_chr_lengths), function(d) {
+        return d;
+      }).enter().append("rect").attr("x", function(d) {
+        if (i === 0) {
+          return _this.x_scale(0);
+        } else {
+          return _this.x_scale(d[1]);
+        }
+      }).attr("y", this.y_buffer).attr("width", function(d) {
+        return _this.x_scale(d[0]);
+      }).attr("height", this.plot_height - this.y_buffer);
+    };
 
-      Manhattan_Plot.prototype.add_chr_labels = function() {
-        var chr_info, chr_names, key,
-          _this = this;
-        chr_names = [];
-        for (key in this.chromosomes) {
-          chr_names.push(key);
+    Manhattan_Plot.prototype.fill_chr_areas2 = function() {
+      var _this = this;
+      console.log("cumu_chr_lengths:", this.cumulative_chr_lengths);
+      console.log("example:", this.x_scale(this.cumulative_chr_lengths[0]));
+      return this.svg.selectAll("rect.chr_fill_area").data(_.zip(this.chr_lengths, this.cumulative_chr_lengths), function(d) {
+        return d;
+      }).enter().append("rect").attr("x", function(d) {
+        if (i === 0) {
+          return _this.x_scale(0);
+        } else {
+          return _this.x_scale(d[1]);
         }
-        chr_info = _.zip(chr_names, this.chr_lengths, this.cumulative_chr_lengths);
-        return this.svg.selectAll("text").data(chr_info, function(d) {
-          return d;
-        }).enter().append("text").text(function(d) {
+      }).attr("y", this.y_buffer).attr("width", function(d) {
+        return _this.x_scale(d[0]);
+      }).attr("height", this.plot_height - this.y_buffer).attr("fill", function(d, i) {
+        return "whitesmoke";
+      });
+    };
+
+    Manhattan_Plot.prototype.add_chr_labels = function() {
+      var chr_info, chr_names, key,
+        _this = this;
+      chr_names = [];
+      for (key in this.chromosomes) {
+        chr_names.push(key);
+      }
+      chr_info = _.zip(chr_names, this.chr_lengths, this.cumulative_chr_lengths);
+      return this.svg.selectAll("text").data(chr_info, function(d) {
+        return d;
+      }).enter().append("text").attr("class", "chr_label").text(function(d) {
+        if (d[0] === "23") {
+          return "X";
+        } else if (d[0] === "24") {
+          return "X/Y";
+        } else {
           return d[0];
-        }).attr("x", function(d) {
-          return _this.x_scale(d[2] - d[1] / 2);
-        }).attr("y", this.plot_height * 0.1).attr("dx", "0em").attr("text-anchor", "middle").attr("font-family", "sans-serif").attr("font-size", "18px").attr("fill", "grey");
-      };
+        }
+      }).attr("x", function(d) {
+        return _this.x_scale(d[2] - d[1] / 2);
+      }).attr("y", this.plot_height * 0.1).attr("dx", "0em").attr("text-anchor", "middle").attr("font-family", "sans-serif").attr("font-size", "18px").attr("fill", "black").on("click", function(d) {
+        var this_chr;
+        this_chr = d;
+        return _this.redraw_plot(d);
+      });
+    };
+
+    Manhattan_Plot.prototype.add_plot_points = function() {
+      var _this = this;
+      return this.plot_point = this.svg.selectAll("circle").data(this.plot_coordinates).enter().append("circle").attr("cx", function(d) {
+        return _this.x_scale(d[0]);
+      }).attr("cy", function(d) {
+        return _this.y_scale(d[1]);
+      }).attr("r", 2).attr("id", function(d) {
+        return "point_" + String(d[2]);
+      }).classed("circle", true).on("mouseover", function(d) {
+        var this_id;
+        console.log("d3.event is:", d3.event);
+        console.log("d is:", d);
+        this_id = "point_" + String(d[2]);
+        return d3.select("#" + this_id).classed("d3_highlight", true).attr("r", 5).attr("fill", "yellow").call(_this.show_marker_in_table(d));
+      }).on("mouseout", function(d) {
+        var this_id;
+        this_id = "point_" + String(d[2]);
+        return d3.select("#" + this_id).classed("d3_highlight", false).attr("r", 2).attr("fill", "black");
+      });
+    };
+
+    Manhattan_Plot.prototype.redraw_plot = function(chr_ob) {
+      console.log("chr_name is:", chr_ob[0]);
+      console.log("chr_length is:", chr_ob[1]);
+      $('#manhattan_plot').remove();
+      $('#manhattan_plot_container').append('<div id="manhattan_plot"></div>');
+      return root.chr_plot = new Chr_Manhattan_Plot(600, 1200, chr_ob);
+    };
+
+    Manhattan_Plot.prototype.create_zoom_pane = function() {
+      var zoom;
+      zoom = d3.behavior.zoom().on("zoom", draw);
+      return this.svg.append("rect").attr("class", "pane").attr("width", this.plot_width).attr("height", this.plot_height).call(zoom);
+    };
+
+    Manhattan_Plot.prototype.draw = function() {
+      this.svg.select("g.x_axis").call(this.xAxis);
+      this.svg.select("g.y_axis").call(this.yAxis);
+      this.svg.select("path.area").attr("d", area);
+      return this.svg.select("path.line").attr("d", line);
+    };
 
-      Manhattan_Plot.prototype.add_plot_points = function() {
-        var _this = this;
-        return this.svg.selectAll("circle").data(this.plot_coordinates).enter().append("circle").attr("cx", function(d) {
-          return parseFloat(_this.x_buffer) + ((parseFloat(_this.plot_width) - parseFloat(_this.x_buffer)) * d[0] / parseFloat(_this.x_max));
-        }).attr("cy", function(d) {
-          return _this.plot_height - ((_this.plot_height - _this.y_buffer) * d[1] / _this.y_max);
-        }).attr("r", 2).attr("id", function(d) {
-          return "point_" + String(d[2]);
-        }).classed("circle", true).on("mouseover", function(d) {
-          var this_id;
-          console.log("d3.event is:", d3.event);
-          console.log("d is:", d);
-          this_id = "point_" + String(d[2]);
-          return d3.select("#" + this_id).classed("d3_highlight", true).attr("r", 5).attr("fill", "yellow").call(_this.show_marker_in_table(d));
-        }).on("mouseout", function(d) {
-          var this_id;
-          this_id = "point_" + String(d[2]);
-          return d3.select("#" + this_id).classed("d3_highlight", false).attr("r", 2).attr("fill", "black").call(_this.show_marker_in_table());
-        });
-      };
+    return Manhattan_Plot;
 
-      return Manhattan_Plot;
+  })();
 
-    })();
-    console.time('Create manhattan plot');
-    new Manhattan_Plot(600, 1200);
-    return console.timeEnd('Create manhattan plot');
-  });
+  root.Manhattan_Plot = new Manhattan_Plot(600, 1200);
 
 }).call(this);
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee
index 1df033d6..84e465e8 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait.coffee
+++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee
@@ -64,8 +64,10 @@ $ ->
     sample_lists = js_data.sample_lists
     sample_group_types = js_data.sample_group_types
 
-    $("#update_bar_chart.btn-group").button()
+    #if $("#update_bar_chart").length
+    #    $("#update_bar_chart.btn-group").button()
     root.bar_chart = new Bar_Chart(sample_lists[0])
+    root.histogram = new Histogram(sample_lists[0])
     new Box_Plot(sample_lists[0])
 
     $('.bar_chart_samples_group').change ->
@@ -73,13 +75,12 @@ $ ->
         $('#bar_chart_container').append('<div id="bar_chart"></div>')
         group = $(this).val()
         if group == "samples_primary"
-            new Bar_Chart(sample_lists[0])
+            root.bar_chart = new Bar_Chart(sample_lists[0])
         else if group == "samples_other"
-            new Bar_Chart(sample_lists[1])
+            root.bar_chart = new Bar_Chart(sample_lists[1])
         else if group == "samples_all"
             all_samples = sample_lists[0].concat sample_lists[1]
-            new Bar_Chart(all_samples)
-        #$(".btn-group").button()
+            root.bar_chart = new Bar_Chart(all_samples)
 
     $('.box_plot_samples_group').change ->
         $('#box_plot').remove()
@@ -93,18 +94,18 @@ $ ->
             all_samples = sample_lists[0].concat sample_lists[1]
             new Box_Plot(all_samples)
 
-    
+
     hide_tabs = (start) ->
         for x in [start..10]
             $("#stats_tabs" + x).hide()
 
+
     # Changes stats table between all, bxd only and non-bxd, etc.
     stats_mdp_change = ->
         selected = $(this).val()
         hide_tabs(0)
         $("#stats_tabs" + selected).show()
 
-    #$(".stats_mdp").change(stats_mdp_change)
 
     change_stats_value = (sample_sets, category, value_type, decimal_places)->
         id = "#" + process_id(category, value_type)
@@ -124,18 +125,16 @@ $ ->
         console.log("*-* the_value:", the_value)
         console.log("*-* current_value:", current_value)
         if the_value != current_value
+            console.log("object:", $(id).html(the_value))
             $(id).html(the_value).effect("highlight")
 
         # We go ahead and always change the title value if we have it
         if title_value
             $(id).attr('title', title_value)
 
+
     update_stat_values = (sample_sets)->
         for category in ['samples_primary', 'samples_other', 'samples_all']
-            #change_stats_value(sample_sets, category, "n_of_samples", 0)
-
-            #for stat in ["mean", "median", "std_dev", "std_error", "min", "max"]
-            #for stat in (row.vn for row in Stat_Table_Rows)
             for row in Stat_Table_Rows
                 console.log("Calling change_stats_value")
                 change_stats_value(sample_sets, category, row.vn, row.digits)
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js
index 90fa8228..d4e01e6d 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait.js
@@ -61,8 +61,8 @@
     var block_by_attribute_value, block_by_index, block_outliers, change_stats_value, create_value_dropdown, edit_data_change, export_sample_table_data, get_sample_table_data, hide_no_value, hide_tabs, make_table, on_corr_method_change, populate_sample_attributes_values_dropdown, process_id, reset_samples_table, sample_group_types, sample_lists, show_hide_outliers, stats_mdp_change, update_stat_values;
     sample_lists = js_data.sample_lists;
     sample_group_types = js_data.sample_group_types;
-    $("#update_bar_chart.btn-group").button();
     root.bar_chart = new Bar_Chart(sample_lists[0]);
+    root.histogram = new Histogram(sample_lists[0]);
     new Box_Plot(sample_lists[0]);
     $('.bar_chart_samples_group').change(function() {
       var all_samples, group;
@@ -70,12 +70,12 @@
       $('#bar_chart_container').append('<div id="bar_chart"></div>');
       group = $(this).val();
       if (group === "samples_primary") {
-        return new Bar_Chart(sample_lists[0]);
+        return root.bar_chart = new Bar_Chart(sample_lists[0]);
       } else if (group === "samples_other") {
-        return new Bar_Chart(sample_lists[1]);
+        return root.bar_chart = new Bar_Chart(sample_lists[1]);
       } else if (group === "samples_all") {
         all_samples = sample_lists[0].concat(sample_lists[1]);
-        return new Bar_Chart(all_samples);
+        return root.bar_chart = new Bar_Chart(all_samples);
       }
     });
     $('.box_plot_samples_group').change(function() {
@@ -123,6 +123,7 @@
       console.log("*-* the_value:", the_value);
       console.log("*-* current_value:", current_value);
       if (the_value !== current_value) {
+        console.log("object:", $(id).html(the_value));
         $(id).html(the_value).effect("highlight");
       }
       if (title_value) {
diff --git a/wqflask/wqflask/static/new/packages/DataTables/js/dataTables.naturalSort.js b/wqflask/wqflask/static/new/packages/DataTables/js/dataTables.naturalSort.js
new file mode 100644
index 00000000..c9e26682
--- /dev/null
+++ b/wqflask/wqflask/static/new/packages/DataTables/js/dataTables.naturalSort.js
@@ -0,0 +1,56 @@
+(function() {

+ 

+/*

+ * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license

+ * Author: Jim Palmer (based on chunking idea from Dave Koelle)

+ * Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo

+ * See: http://js-naturalsort.googlecode.com/svn/trunk/naturalSort.js

+ */

+function naturalSort (a, b) {

+    var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,

+        sre = /(^[ ]*|[ ]*$)/g,

+        dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,

+        hre = /^0x[0-9a-f]+$/i,

+        ore = /^0/,

+        // convert all to strings and trim()

+        x = a.toString().replace(sre, '') || '',

+        y = b.toString().replace(sre, '') || '',

+        // chunk/tokenize

+        xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),

+        yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),

+        // numeric, hex or date detection

+        xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),

+        yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;

+    // first try and sort Hex codes or Dates

+    if (yD)

+        if ( xD < yD ) return -1;

+        else if ( xD > yD )  return 1;

+    // natural sorting through split numeric strings and default strings

+    for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {

+        // find floats not starting with '0', string or 0 if not defined (Clint Priest)

+        var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;

+        var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;

+        // handle numeric vs string comparison - number < string - (Kyle Adams)

+        if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1;

+        // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'

+        else if (typeof oFxNcL !== typeof oFyNcL) {

+            oFxNcL += '';

+            oFyNcL += '';

+        }

+        if (oFxNcL < oFyNcL) return -1;

+        if (oFxNcL > oFyNcL) return 1;

+    }

+    return 0;

+}

+ 

+jQuery.extend( jQuery.fn.dataTableExt.oSort, {

+    "natural-asc": function ( a, b ) {

+        return naturalSort(a,b);

+    },

+ 

+    "natural-desc": function ( a, b ) {

+        return naturalSort(a,b) * -1;

+    }

+} );

+ 

+}());
\ No newline at end of file
diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html
index d177a7bd..a7d7b513 100644
--- a/wqflask/wqflask/templates/index_page.html
+++ b/wqflask/wqflask/templates/index_page.html
@@ -17,7 +17,7 @@
         <div class="row">
             <div class="span3 bs-docs-sidebar">
               <ul class="nav nav-list bs-docs-sidenav">
-                <li><a href="#quick-search"><i class="icon-chevron-right"></i> Quick Search</a></li>
+<!--                <li><a href="#quick-search"><i class="icon-chevron-right"></i> Quick Search</a></li>-->
                 <li><a href="#search"><i class="icon-chevron-right"></i> Search</a></li>
                 <li><a href="#getting-started"><i class="icon-chevron-right"></i> Getting started</a></li>
                 <li><a href="#advanced"><i class="icon-chevron-right"></i> Advanced commands</a></li>
@@ -27,7 +27,7 @@
             </div>
             
             <div class="span9">
-                <section id="quick-search">
+<!--                <section id="quick-search">
                     <div class="page-header">
                         <h1>Quick search</h1>
                     </div>
@@ -52,7 +52,7 @@
                             </div>
                         </fieldset>
                     </form>
-                </section>
+                </section>-->
                 <section id="search">
                     <div class="page-header">
                         <h1>Select and search</h1>
diff --git a/wqflask/wqflask/templates/interval_mapping.html b/wqflask/wqflask/templates/interval_mapping.html
index e4e08388..e4b93bf4 100644
--- a/wqflask/wqflask/templates/interval_mapping.html
+++ b/wqflask/wqflask/templates/interval_mapping.html
@@ -77,7 +77,6 @@
     <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>

     <script language="javascript" type="text/javascript" src="/static/packages/underscore/underscore-min.js"></script>

 

-    

     <script type="text/javascript" charset="utf-8">

         $(document).ready( function () {

             console.time("Creating table");

diff --git a/wqflask/wqflask/templates/marker_regression.html b/wqflask/wqflask/templates/marker_regression.html
index 64d2e9b7..05fb9845 100644
--- a/wqflask/wqflask/templates/marker_regression.html
+++ b/wqflask/wqflask/templates/marker_regression.html
@@ -18,14 +18,17 @@
                 Manhattan Plot
             </h2>
         </div>
-        <div id="manhattan_plots" class="manhattan_plots">
-            
+        <div id="manhattan_plot_container" class="manhattan_plot_container">
+            <div id="manhattan_plot" class="manhattan_plots">
+                
+            </div>
         </div>
         <div>
             <h2>
                 Genome Association Results
             </h2>
         </div>
+
         <table cellpadding="0" cellspacing="0" border="0" id="qtl_results" class="table table-hover table-striped table-bordered">
             <thead>
                 <tr>
@@ -38,17 +41,18 @@
             </thead>
             <tbody>
                 {% for marker in qtl_results %}
-                <tr>
-                    <td>{{loop.index}}</td>
-                    <td>{{marker.lod_score}}</td>
-                    <td>{{marker.chr}}</td>
-                    <td>{{marker.Mb}}</td>
-                    <td>{{marker.name}}</td>
-                </tr>
+                    {% if marker.lod_score > lod_cutoff %}
+                    <tr>
+                        <td>{{loop.index}}</td>
+                        <td>{{marker.lod_score}}</td>
+                        <td>{{marker.chr}}</td>
+                        <td>{{marker.Mb}}</td>
+                        <td>{{marker.name}}</td>
+                    </tr>
+                    {% endif %}
                 {% endfor %}
             </tbody>
         </table>
-    
     </div>
 
     <!-- End of body -->
@@ -61,15 +65,16 @@
     </script>
 
     <!--[if lt IE 9]>
-        <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>
+<!--        <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>-->
     <![endif]-->
     <script language="javascript" type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
-    <script language="javascript" type="text/javascript" src="/static/new/javascript/marker_regression.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
     <script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
     <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
     <script language="javascript" type="text/javascript" src="/static/packages/underscore/underscore-min.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/new/javascript/marker_regression.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/new/javascript/chr_manhattan_plot.js"></script>
 
     
     <script type="text/javascript" charset="utf-8">
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index 86891bb0..e15d043b 100644
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -58,9 +58,49 @@
     <script type="text/javascript" src="/static/new/javascript/box.js"></script>
     <script type="text/javascript" src="/static/new/javascript/get_traits_from_collection.js"></script>    
     <script type="text/javascript" src="/static/new/javascript/bar_chart.js"></script>
+    <script type="text/javascript" src="/static/new/javascript/histogram.js"></script>
     <script type="text/javascript" src="/static/new/javascript/box_plot.js"></script>
     
     <script type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script>
     <script type="text/javascript" src="/static/new/javascript/show_trait.js"></script>
     <script type="text/javascript" src="/static/new/javascript/validation.js"></script>
+    
+    <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
+    
+    <script type="text/javascript" charset="utf-8">
+        $(document).ready( function () {
+            console.time("Creating table");
+            $('#samples_primary, #samples_other').dataTable( {
+                //"sDom": "<<'span3'l><'span3'T><'span4'f>'row-fluid'r>t<'row-fluid'<'span6'i><'span6'p>>",
+                "aoColumns": [
+                    { "sType": "natural" },
+                    null,
+                    null,
+                    { "bSortable": false },
+                    null
+                ],
+                "sDom": "ftr",
+                "oTableTools": {
+                    "aButtons": [
+                        "copy",
+                        "print",
+                        {
+                            "sExtends":    "collection",
+                            "sButtonText": 'Save <span class="caret" />',
+                            "aButtons":    [ "csv", "xls", "pdf" ]
+                        }
+                    ],
+                    "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
+                },
+                "bPaginate": false,
+                "bLengthChange": true,
+                "bDeferRender": true,
+                "bSortClasses": false
+            } );
+            console.timeEnd("Creating table");
+        });
+    </script>
 {% endblock %}
diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html
index 84c606b9..e7df3b13 100644
--- a/wqflask/wqflask/templates/show_trait_edit_data.html
+++ b/wqflask/wqflask/templates/show_trait_edit_data.html
@@ -82,75 +82,73 @@
         <div>
             <h3>{{ sample_type.header }}</h3>
 
-            <table class="table table-hover table-striped"  {# Todo: Enable sorting on table #}
+            <table cellpadding="0" cellspacing="0" border="0" class="table table-hover table-striped table-bordered"
                    id="samples_{{ sample_type.sample_group_type }}">
-                <tr>
-                    <th>Index</th>
-
-                    <th>Sample</th>
-
-                    <th>Value</th>
-                    {% if sample_type.se_exists() %}
-                    <th>&nbsp;</th>
-
-                    <th>SE</th>
-                    {% endif %}
-
-                    {% for attribute in sample_type.attributes|sort() %}
-                    <th>
-                        {{ sample_type.attributes[attribute].name }}
-                    </th>
+                <thead>
+                    <tr>
+                        <td>Index</td>
+                        <td>Sample</td>
+                        <td>Value</td>
+                        {% if sample_type.se_exists() %}
+                        <td>&nbsp;</td>
+                        <td>SE</td>
+                        {% endif %}
+                        {% for attribute in sample_type.attributes|sort() %}
+                        <td>
+                            {{ sample_type.attributes[attribute].name }}
+                        </td>
+                        {% endfor %}
+                    </tr>
+                </thead>
+                <tbody>
+                    {% for sample in sample_type.sample_list %}
+                    <tr class="{{ sample.class_outlier }} value_se" id="{{ sample.this_id }}">
+                        <td class="column_name-Index">
+                            {{ loop.index }}
+                            <input type="checkbox" name="selectCheck"
+                                   class="checkbox edit_sample_checkbox"
+                                   value="{{ sample.name }}" checked="checked">
+                        </td>
+        
+                        <td class="column_name-Sample">
+                            <span class="edit_sample_sample_name">
+                                {{ sample.name }}
+                             </span>
+                        </td>
+        
+                        {# Todo: Add IDs #}
+                        <td class="column_name-Value">
+                          <input type="text" data-value="{{ sample.display_value }}" name="{{ 'value:' + sample.name }}"
+                                 class="trait_value_input edit_sample_value"
+                                 value="{{ sample.display_value }}"
+                                 size=8 maxlength=8
+                          >
+                        </td>
+        
+                        {% if sample_type.se_exists() %}
+                        <td>
+                          ±
+                        </td>
+        
+                        {# Todo: Add IDs #}
+                        <td class="column_name-SE">
+                          <input type="text" data-value="{{ sample.display_variance }}" name="{{ 'variance:' + sample.name}}"
+                                 class="trait_value_input edit_sample_se"
+                                 value="{{ sample.display_variance }}"
+                                 size=8 maxlength=8
+                          >
+                        </td>
+                        {% endif %}
+        
+                        {# Loop through each attribute type and input value #}
+                        {% for attribute in sample_type.attributes|sort() %}
+                        <td class="std_cell column_name-{{ sample_type.attributes[attribute].name.replace(' ', '_') }}">
+                          {{ sample.extra_attributes[sample_type.attributes[attribute].name] }}
+                        </td>
+                        {% endfor %}
+                    </tr>
                     {% endfor %}
-                </tr>
-
-                {% for sample in sample_type.sample_list %}
-                <tr class="{{ sample.class_outlier }} value_se" id="{{ sample.this_id }}">
-                <td class="column_name-Index">
-                    {{ loop.index }}
-                    <input type="checkbox" name="selectCheck"
-                           class="checkbox edit_sample_checkbox"
-                           value="{{ sample.name }}" checked="checked">
-                </td>
-
-                <td class="column_name-Sample">
-                    <span class="edit_sample_sample_name">
-                        {{ sample.name }}
-                     </span>
-                </td>
-
-                {# Todo: Add IDs #}
-                <td class="column_name-Value">
-                  <input type="text" data-value="{{ sample.display_value }}" name="{{ 'value:' + sample.name }}"
-                         class="trait_value_input edit_sample_value"
-                         value="{{ sample.display_value }}"
-                         size=8 maxlength=8
-                  >
-                </td>
-
-                {% if sample_type.se_exists() %}
-                <td>
-                  ±
-                </td>
-
-                {# Todo: Add IDs #}
-                <td class="column_name-SE">
-                  <input type="text" data-value="{{ sample.display_variance }}" name="{{ 'variance:' + sample.name}}"
-                         class="trait_value_input edit_sample_se"
-                         value="{{ sample.display_variance }}"
-                         size=8 maxlength=8
-                  >
-                </td>
-                {% endif %}
-
-                {# Loop through each attribute type and input value #}
-                {% for attribute in sample_type.attributes|sort() %}
-                <td class="std_cell column_name-{{ sample_type.attributes[attribute].name.replace(' ', '_') }}">
-                  {{ sample.extra_attributes[sample_type.attributes[attribute].name] }}
-                </td>
-                {% endfor %}
-              </tr>
-              {% endfor %}
-
+                </tbody>
             </table>
         </div>
         {% endfor %}
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index 58ee8982..cfa49456 100644
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -133,7 +133,7 @@
                         <div class="controls">
                             <input name="num_perm" value="2000" type="text" />
                         </div>
-                    </div>           -->         
+                    </div>           -->
                     
                     <div class="control-group">
                         <div class="controls">
diff --git a/wqflask/wqflask/templates/show_trait_statistics_new.html b/wqflask/wqflask/templates/show_trait_statistics_new.html
index 6d6b1d24..28f7e0c7 100644
--- a/wqflask/wqflask/templates/show_trait_statistics_new.html
+++ b/wqflask/wqflask/templates/show_trait_statistics_new.html
@@ -8,6 +8,9 @@
                     <a href="#bar_chart_tab" data-toggle="tab">Bar Chart</a>
                 </li>
                 <li>
+                    <a href="#histogram_tab" data-toggle="tab">Histogram</a>
+                </li>
+                <li>
                     <a href="#box_plot_tab" data-toggle="tab">Box Plot</a>
                 </li>
             </ul>
@@ -51,7 +54,20 @@
                         <div id="bar_chart"></div>
                     </div>
                 </div>
-                <div class="tab-pane active" id="box_plot_tab">
+                <div class="tab-pane" id="histogram_tab">
+                    {% if sample_groups|length > 1 %}
+                    <select class="histogram_samples_group">
+                        {% for group, pretty_group in sample_group_types.items() %}
+                            <option value="{{ group }}">{{ pretty_group }}</option>
+                        {% endfor %}
+                    </select>
+                    <br><br>
+                    {% endif %}
+                    <div id="histogram_container">
+                        <div id="histogram"></div>
+                    </div>
+                </div>
+                <div class="tab-pane" id="box_plot_tab">
                     {% if sample_groups|length > 1 %}
                     <select class="box_plot_samples_group">
                         {% for group, pretty_group in sample_group_types.items() %}
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index 828199c5..89820145 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -243,7 +243,12 @@ def marker_regression_page():
             print("  ---**--- {}: {}".format(type(template_vars.__dict__[item]), item))
 
         #causeerror
-        Redis.set(key, pickle.dumps(result, pickle.HIGHEST_PROTOCOL))
+        
+        #qtl_length = len(result['js_data']['qtl_results'])
+        #print("qtl_length:", qtl_length)
+        pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL)
+        print("pickled result length:", len(pickled_result))
+        Redis.set(key, pickled_result)
         Redis.expire(key, 60*60)
 
     with Bench("Rendering template"):