about summary refs log tree commit diff
path: root/wqflask/wqflask
diff options
context:
space:
mode:
authorMuriithi Frederick Muriuki2018-03-31 14:45:17 +0300
committerMuriithi Frederick Muriuki2018-03-31 14:45:17 +0300
commit31747256e466456cc88aac60780836a6534f18cd (patch)
treea7b371e4ec217ffb37594e15f5e603ae28511dc2 /wqflask/wqflask
parentcfce6d80be4fb38573c37d1943db2687d54cf2fc (diff)
parent5424741a4a126bfd5f04df7cbcdc30b4e1376b86 (diff)
downloadgenenetwork2-31747256e466456cc88aac60780836a6534f18cd.tar.gz
Merge branch 'testing' of https://github.com/genenetwork/genenetwork2 into testing
* Fix conflicts
Diffstat (limited to 'wqflask/wqflask')
-rw-r--r--wqflask/wqflask/__init__.py4
-rw-r--r--wqflask/wqflask/collect.py51
-rw-r--r--wqflask/wqflask/correlation/show_corr_results.py116
-rw-r--r--wqflask/wqflask/correlation_matrix/show_corr_matrix.py9
-rw-r--r--wqflask/wqflask/gsearch.py6
-rw-r--r--wqflask/wqflask/marker_regression/gemma_mapping.py22
-rw-r--r--wqflask/wqflask/marker_regression/marker_regression.py1
-rw-r--r--wqflask/wqflask/marker_regression/marker_regression_gn1.py2
-rw-r--r--wqflask/wqflask/marker_regression/qtlreaper_mapping.py17
-rw-r--r--wqflask/wqflask/search_results.py23
-rw-r--r--wqflask/wqflask/static/dbdoc/TODO.md1
-rw-r--r--wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js130
-rw-r--r--wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js137
-rw-r--r--wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js5
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait.js3
-rw-r--r--wqflask/wqflask/templates/collections/list.html12
-rw-r--r--wqflask/wqflask/templates/corr_scatterplot.html176
-rw-r--r--wqflask/wqflask/templates/correlation_matrix.html3
-rw-r--r--wqflask/wqflask/templates/correlation_page.html28
-rw-r--r--wqflask/wqflask/templates/empty_collection.html15
-rw-r--r--wqflask/wqflask/templates/new_security/login_user.html10
-rw-r--r--wqflask/wqflask/templates/show_trait_calculate_correlations.html106
-rw-r--r--wqflask/wqflask/templates/show_trait_mapping_tools.html232
-rw-r--r--wqflask/wqflask/user_manager.py52
-rw-r--r--wqflask/wqflask/views.py75
25 files changed, 604 insertions, 632 deletions
diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py
index 2188ce17..bc8e9900 100644
--- a/wqflask/wqflask/__init__.py
+++ b/wqflask/wqflask/__init__.py
@@ -13,8 +13,8 @@ logging.basicConfig(level=logging.INFO)
 app = Flask(__name__)
 
 app.config.from_object('cfg.default_settings')   # Get the defaults from cfg.default_settings
-app.config.from_envvar('WQFLASK_SETTINGS')       # See http://flask.pocoo.org/docs/config/#configuring-from-files
-# Note we also use WQFLASK_OVERRIDES
+app.config.from_envvar('GN2_SETTINGS')       # See http://flask.pocoo.org/docs/config/#configuring-from-files
+# Note no longer use the badly named WQFLASK_OVERRIDES (nyi)
 
 app.jinja_env.globals.update(
     undefined = jinja2.StrictUndefined,
diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py
index 2f6c3a96..629977ac 100644
--- a/wqflask/wqflask/collect.py
+++ b/wqflask/wqflask/collect.py
@@ -36,6 +36,10 @@ from utility.formatting import numify
 from base import trait
 from base.data_set import create_dataset
 
+import logging
+from utility.logger import getLogger
+logger = getLogger(__name__)
+
 def get_collection():
     if g.user_session.logged_in:
         return UserCollection()
@@ -93,7 +97,7 @@ class AnonCollection(object):
         self.traits = list(process_traits(params['traits']))
         #len_before = len(Redis.smembers(self.key))
         existing_collections = Redis.get(self.key)
-        print("existing_collections:", existing_collections)
+        logger.debug("existing_collections:", existing_collections)
         if existing_collections != None and existing_collections != "None":
             collections_list = json.loads(existing_collections)
             collection_position = 0 #ZS: Position of collection in collection_list, if it exists
@@ -158,8 +162,8 @@ class UserCollection(object):
     """User is logged in"""
 
     def add_traits(self, params, collection_name):
-        print("---> params are:", params.keys())
-        print("     type(params):", type(params))
+        logger.debug("---> params are:", params.keys())
+        logger.debug("     type(params):", type(params))
         if collection_name=="Default":
             uc = g.user_session.user_ob.get_collection_by_name("Default")
             # Doesn't exist so we'll create it
@@ -187,7 +191,7 @@ class UserCollection(object):
 
         db_session.commit()
 
-        print("added to existing, now set is:" + str(uc.members))
+        logger.debug("added to existing, now set is:" + str(uc.members))
         report_change(len_before, len_now)
 
         # Probably have to change that
@@ -210,12 +214,12 @@ def process_traits(unprocessed_traits):
 def report_change(len_before, len_now):
     new_length = len_now - len_before
     if new_length:
-        print("We've added {} to your collection.".format(
+        logger.debug("We've added {} to your collection.".format(
             numify(new_length, 'new trait', 'new traits')))
         flash("We've added {} to your collection.".format(
             numify(new_length, 'new trait', 'new traits')))
     else:
-        print("No new traits were added.")
+        logger.debug("No new traits were added.")
 
 
 @app.route("/collections/add")
@@ -224,7 +228,7 @@ def collections_add():
 
     if g.user_session.logged_in:
         user_collections = g.user_session.user_ob.user_collections
-        print("user_collections are:", user_collections)
+        logger.debug("user_collections are:", user_collections)
         return render_template("collections/add.html",
                                traits = traits,
                                collections = user_collections,
@@ -246,11 +250,11 @@ def collections_new():
     if "sign_in" in params:
         return redirect(url_for('login'))
     if "create_new" in params:
-        print("in create_new")
+        logger.debug("in create_new")
         collection_name = params['new_collection']
         return create_new(collection_name)
     elif "add_to_existing" in params:
-        print("in add to existing")
+        logger.debug("in add to existing")
         collection_name = params['existing_collection'].split(":")[1]
         if g.user_session.logged_in:
             return UserCollection().add_traits(params, collection_name)
@@ -270,7 +274,7 @@ def create_new(collection_name):
     if g.user_session.logged_in:
         uc = model.UserCollection()
         uc.name = collection_name
-        print("user_session:", g.user_session.__dict__)
+        logger.debug("user_session:", g.user_session.__dict__)
         uc.user = g.user_session.user_id
         uc.members = json.dumps(list(traits))
         db_session.add(uc)
@@ -286,17 +290,17 @@ def create_new(collection_name):
 @app.route("/collections/list")
 def list_collections():
     params = request.args
-    print("PARAMS:", params)
+    logger.debug("PARAMS:", params)
     if g.user_session.logged_in:
         user_collections = list(g.user_session.user_ob.user_collections)
-        print("user_collections are:", user_collections)
+        logger.debug("user_collections are:", user_collections)
         return render_template("collections/list.html",
                                params = params,
                                collections = user_collections,
                                )
     else:
         anon_collections = user_manager.AnonUser().get_collections()
-        print("anon_collections are:", anon_collections)
+        logger.debug("anon_collections are:", anon_collections)
         return render_template("collections/list.html",
                                params = params,
                                collections = anon_collections)
@@ -305,17 +309,17 @@ def list_collections():
 @app.route("/collections/remove", methods=('POST',))
 def remove_traits():
     params = request.form
-    print("params are:", params)
+    logger.debug("params are:", params)
 
     if "uc_id" in params:
         uc_id = params['uc_id']
         uc = model.UserCollection.query.get(uc_id)
         traits_to_remove = params.getlist('traits[]')
         traits_to_remove = process_traits(traits_to_remove)
-        print("\n\n  after processing, traits_to_remove:", traits_to_remove)
+        logger.debug("\n\n  after processing, traits_to_remove:", traits_to_remove)
         all_traits = uc.members_as_set()
         members_now = all_traits - traits_to_remove
-        print("  members_now:", members_now)
+        logger.debug("  members_now:", members_now)
         uc.members = json.dumps(list(members_now))
         uc.changed_timestamp = datetime.datetime.utcnow()
         db_session.commit()
@@ -332,7 +336,7 @@ def remove_traits():
 @app.route("/collections/delete", methods=('POST',))
 def delete_collection():
     params = request.form
-    print("params:", params)
+    logger.debug("params:", params)
     if g.user_session.logged_in:
         uc_id = params['uc_id']
         if len(uc_id.split(":")) > 1:
@@ -349,8 +353,11 @@ def delete_collection():
             db_session.delete(uc)
             db_session.commit()
     else:
-        collection_name = params['collection_name']
-        user_manager.AnonUser().delete_collection(collection_name)
+        if "collection_name" in params:
+            collection_name = params['collection_name']
+        else:
+            for this_collection in params['uc_id'].split(":"):
+                user_manager.AnonUser().delete_collection(this_collection)
 
     flash("We've deleted the collection: {}.".format(collection_name), "alert-info")
 
@@ -360,7 +367,7 @@ def delete_collection():
 @app.route("/collections/view")
 def view_collection():
     params = request.args
-    print("PARAMS in view collection:", params)
+    logger.debug("PARAMS in view collection:", params)
 
     if "uc_id" in params:
         uc_id = params['uc_id']
@@ -376,7 +383,7 @@ def view_collection():
         #this_collection = user_collections[params['collection_id']]
         traits = this_collection['members']
 
-    print("in view_collection traits are:", traits)
+    logger.debug("in view_collection traits are:", traits)
 
     trait_obs = []
     json_version = []
@@ -402,7 +409,7 @@ def view_collection():
         collection_info = dict(trait_obs=trait_obs,
                                collection_name=this_collection['name'])
     if "json" in params:
-        print("json_version:", json_version)
+        logger.debug("json_version:", json_version)
         return json.dumps(json_version)
     else:
         return render_template("collections/view.html",
diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py
index 3d1c0d17..2c6c3a14 100644
--- a/wqflask/wqflask/correlation/show_corr_results.py
+++ b/wqflask/wqflask/correlation/show_corr_results.py
@@ -32,6 +32,7 @@ import pp
 import math
 import collections
 import resource
+import json
 
 import scipy
 
@@ -51,6 +52,8 @@ import utility.webqtlUtil #this is for parallel computing only.
 from wqflask.correlation import correlation_functions
 from utility.benchmark import Bench
 import utility.webqtlUtil
+from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string
+from wqflask import user_manager
 
 from MySQLdb import escape_string as escape
 
@@ -75,47 +78,6 @@ def print_mem(stage=""):
     mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
     #print("{}: {}".format(stage, mem/1024))
 
-def is_float(value):
-    try:
-        float(value)
-        return True
-    except:
-        return False
-
-def is_int(value):
-    try:
-        int(value)
-        return True
-    except:
-        return False
-
-def is_str(value):
-    if value is None:
-        return False
-    try:
-        str(value)
-        return True
-    except:
-        return False
-
-def get_float(vars,name,default=None):
-    if name in vars:
-        if is_float(vars[name]):
-            return float(vars[name])
-    return None
-
-def get_int(vars,name,default=None):
-    if name in vars:
-        if is_int(vars[name]):
-            return float(vars[name])
-    return default
-
-def get_string(vars,name,default=None):
-    if name in vars:
-        if not vars[name] is None:
-            return str(vars[name])
-    return default
-
 class AuthException(Exception):
     pass
 
@@ -248,7 +210,7 @@ class CorrelationResults(object):
                         else:
                             self.this_trait_vals.append("None")
                     num_overlap = len(self.this_trait_vals)
-
+                    logger.debug("DOING PARALLEL")
                     self.do_parallel_correlation(db_filename, num_overlap)
                 else:
                     for trait, values in self.target_dataset.trait_data.iteritems():
@@ -335,6 +297,7 @@ class CorrelationResults(object):
 
             #print("self.correlation_results: ", pf(self.correlation_results))
 
+        self.json_results = generate_corr_json(self.correlation_results, self.this_trait, self.dataset, self.target_dataset)
 
         #XZ, 09/18/2008: get all information about the user selected database.
         #target_db_name = fd.corr_dataset
@@ -1195,6 +1158,17 @@ class CorrelationResults(object):
             import math
             import reaper
 
+            def cmpOrder2(A,B):
+                try:
+                    if A[-1] < B[-1]:
+                        return -1
+                    elif A[-1] == B[-1]:
+                        return 0
+                    else:
+                        return 1
+                except:
+                    return 0
+
             def calCorrelation(dbdata,userdata,N):
                 X = []
                 Y = []
@@ -1420,3 +1394,61 @@ class CorrelationResults(object):
         # for one_result in results:
             # for one_traitinfo in one_result:
                 # allcorrelations.append( one_traitinfo )
+
+def generate_corr_json(corr_results, this_trait, dataset, target_dataset):
+    results_list = []
+    for i, trait in enumerate(corr_results):
+        results_dict = {}
+        results_dict['checkbox'] = "<INPUT TYPE='checkbox' NAME='searchResult' class='checkbox trait_checkbox' style='padding-right: 0px;' VALUE='" + user_manager.data_hmac('{}:{}'.format(trait.name, trait.dataset.name)) + "'>"
+        results_dict['index'] = i + 1
+        results_dict['trait_id'] = "<a href='/show_trait?trait_id="+str(trait.name)+"&dataset="+str(dataset.name)+"'>"+str(trait.name)+"</a>"
+        if target_dataset.type == "ProbeSet":
+            results_dict['symbol'] = trait.symbol
+            results_dict['description'] = trait.description_display
+            results_dict['location'] = trait.location_repr
+            results_dict['mean'] = float(trait.mean)
+            if trait.LRS_score_repr != "N/A":
+                results_dict['lrs_score'] = "%.1f" % float(trait.LRS_score_repr)
+            else:
+                results_dict['lrs_score'] = "N/A"
+            results_dict['lrs_location'] = trait.LRS_location_repr
+            if trait.additive != "":
+                results_dict['additive'] = "%0.3f" % float(trait.additive)
+            else:
+                results_dict['additive'] = "N/A"
+            results_dict['sample_r'] = "<a target='_blank' href='corr_scatter_plot?dataset_1=" + str(dataset.name) + "&dataset_2=" + str(trait.dataset.name) + "&trait_1=" + str(this_trait.name) + "&trait_2=" + str(trait.name) + "'>" + "%0.3f" % float(trait.sample_r) + "</a>"
+            results_dict['num_overlap'] = trait.num_overlap
+            results_dict['sample_p'] = "%0.3e" % float(trait.sample_p)
+            if trait.lit_corr == "" or trait.lit_corr == 0:
+                results_dict['lit_corr'] = "--"
+            else:
+                results_dict['lit_corr'] = "%0.3f" % float(trait.lit_corr)
+            if trait.tissue_corr == "" or trait.tissue_corr == 0:
+                results_dict['tissue_corr'] = "--"
+            else:
+                results_dict['tissue_corr'] = "%0.3f" % float(trait.tissue_corr)
+        elif target_dataset.type == "Publish":
+            results_dict['description'] = trait.description_display
+            results_dict['authors'] = trait.authors
+            if trait.pubmed_id:
+                results_dict['pubmed'] = "<a href='" + trait.pubmed_link + "'> " + trait.pubmed_text + "</a>"
+            else:
+                results_dict['pubmed'] = "N/A"
+            results_dict['lrs_score'] = trait.LRS_score_repr
+            results_dict['lrs_location'] = trait.LRS_location_repr
+            if trait.additive != "":
+                results_dict['additive'] = "%0.3f" % float(trait.additive)
+            else:
+                results_dict['additive'] = "N/A"
+            results_dict['sample_r'] = "<a target='_blank' href='corr_scatter_plot?dataset_1=" + str(dataset.name) + "&dataset_2=" + str(trait.dataset.name) + "&trait_1=" + str(this_trait.name) + "&trait_2=" + str(trait.name) + "'>" + "%0.3f" % trait.sample_r + "</a>"
+            results_dict['num_overlap'] = trait.num_overlap
+            results_dict['sample_p'] = "%0.3e" % float(trait.sample_p)
+        else:
+            results_dict['lrs_location'] = trait.LRS_location_repr
+            results_dict['sample_r'] = "<a target='_blank' href='corr_scatter_plot?dataset_1=" + str(dataset.name) + "&dataset_2=" + str(trait.dataset.name) + "&trait_1=" + str(this_trait.name) + "&trait_2=" + str(trait.name) + "'>" + "%0.3f" % float(trait.sample_r) + "</a>"
+            results_dict['num_overlap'] = trait.num_overlap
+            results_dict['sample_p'] = "%0.3e" % float(trait.sample_p)
+
+        results_list.append(results_dict)
+
+    return json.dumps(results_list)
diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
index b34beb7b..077386a3 100644
--- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
+++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
@@ -173,9 +173,12 @@ class CorrelationMatrix(object):
             for sample in self.all_sample_list:
                 groups.append(1)
 
-            pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors)
-
-            self.loadings_array = self.process_loadings()
+            try:
+                self.pca_works = "True"
+                pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors)
+                self.loadings_array = self.process_loadings()
+            except:
+                self.pca_works = "False"
 
             self.js_data = dict(traits = [trait.name for trait in self.traits],
                                 groups = groups,
diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py
index e33e04e1..fe1e17d2 100644
--- a/wqflask/wqflask/gsearch.py
+++ b/wqflask/wqflask/gsearch.py
@@ -5,6 +5,7 @@ from base.data_set import create_dataset
 from base.trait import GeneralTrait
 from db import webqtlDatabaseFunction
 
+from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string
 from utility.benchmark import Bench
 
 from utility.logger import getLogger
@@ -13,8 +14,13 @@ logger = getLogger(__name__)
 class GSearch(object):
 
     def __init__(self, kw):
+        assert('type' in kw)
+        assert('terms' in kw)
+
         self.type = kw['type']
         self.terms = kw['terms']
+        assert(is_str(self.type))
+
         if self.type == "gene":
             sql = """
                 SELECT
diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py
index 68920130..7563eb2c 100644
--- a/wqflask/wqflask/marker_regression/gemma_mapping.py
+++ b/wqflask/wqflask/marker_regression/gemma_mapping.py
@@ -3,7 +3,7 @@ import os, math, string, random, json
 from base import webqtlConfig
 from base.trait import GeneralTrait
 from base.data_set import create_dataset
-from utility.tools import flat_files, GEMMA_COMMAND, GEMMA_WRAPPER_COMMAND, TEMPDIR, assert_bin, assert_file
+from utility.tools import flat_files, GEMMA_COMMAND, GEMMA_WRAPPER_COMMAND, TEMPDIR
 
 import utility.logger
 logger = utility.logger.getLogger(__name__ )
@@ -11,7 +11,6 @@ logger = utility.logger.getLogger(__name__ )
 def run_gemma(this_dataset, samples, vals, covariates, method, use_loco):
     """Generates p-values for each marker using GEMMA"""
 
-    assert_bin(GEMMA_COMMAND);
     if this_dataset.group.genofile != None:
         genofile_name = this_dataset.group.genofile[:-5]
     else:
@@ -193,7 +192,7 @@ def parse_gemma_output(genofile_name):
                 # if marker['chr'] != previous_chr:
                     # previous_chr = marker['chr']
                 marker['Mb'] = float(line.split("\t")[2]) / 1000000
-                marker['p_value'] = float(line.split("\t")[10])
+                marker['p_value'] = float(line.split("\t")[11])
                 if math.isnan(marker['p_value']) or (marker['p_value'] <= 0):
                     marker['lod_score'] = 0
                     #marker['lrs_value'] = 0
@@ -203,20 +202,15 @@ def parse_gemma_output(genofile_name):
                 marker_obs.append(marker)
 
                 included_markers.append(line.split("\t")[1])
-                p_values.append(float(line.split("\t")[10]))
+                p_values.append(float(line.split("\t")[11]))
 
     return marker_obs
 
 def parse_loco_output(this_dataset, gwa_output_filename):
 
     output_filelist = []
-    jsonfn = "{}/gn2/".format(TEMPDIR) + gwa_output_filename + ".json"
-    assert_file(jsonfn)
-    try:
-        with open(jsonfn) as data_file:
-            data = json.load(data_file)
-    except:
-        logger.error("Can not parse "+jsonfn)
+    with open("{}/gn2/".format(TEMPDIR) + gwa_output_filename + ".json") as data_file:
+       data = json.load(data_file)
 
     files = data['files']
     for file in files:
@@ -241,7 +235,7 @@ def parse_loco_output(this_dataset, gwa_output_filename):
                     else:
                         marker['chr'] = line.split("\t")[0]
                     marker['Mb'] = float(line.split("\t")[2]) / 1000000
-                    marker['p_value'] = float(line.split("\t")[10])
+                    marker['p_value'] = float(line.split("\t")[11])
                     if math.isnan(marker['p_value']) or (marker['p_value'] <= 0):
                         marker['lod_score'] = 0
                         #marker['lrs_value'] = 0
@@ -251,6 +245,6 @@ def parse_loco_output(this_dataset, gwa_output_filename):
                     marker_obs.append(marker)
 
                     included_markers.append(line.split("\t")[1])
-                    p_values.append(float(line.split("\t")[10]))
+                    p_values.append(float(line.split("\t")[11]))
 
-    return marker_obs
+    return marker_obs
\ No newline at end of file
diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py
index c189fb96..3ec61e55 100644
--- a/wqflask/wqflask/marker_regression/marker_regression.py
+++ b/wqflask/wqflask/marker_regression/marker_regression.py
@@ -228,6 +228,7 @@ class MarkerRegression(object):
             results, self.json_data, self.perm_output, self.suggestive, self.significant, self.bootstrap_results = qtlreaper_mapping.gen_reaper_results(self.this_trait,
                                                                                                                                                         self.dataset,
                                                                                                                                                         self.samples,
+                                                                                                                                                        self.vals,
                                                                                                                                                         self.json_data,
                                                                                                                                                         self.num_perm,
                                                                                                                                                         self.bootCheck,
diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py
index 211cf187..66884b0c 100644
--- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py
+++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py
@@ -1204,6 +1204,8 @@ class MarkerRegression(object):
         else:
             if self.mapping_method == "gemma" or self.mapping_method == "gemma_bimbam":
                 string2 = 'Using GEMMA mapping method with no control for other QTLs.'
+                if self.covariates != "":
+                    string3 = 'Using following traits as covariates: ' + self.covariates
             elif self.mapping_method == "rqtl_plink" or self.mapping_method == "rqtl_geno":
                 string2 = 'Using R/qtl mapping method with no control for other QTLs.'
             elif self.mapping_method == "plink":
diff --git a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
index 50228b5e..6b58190f 100644
--- a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
+++ b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
@@ -1,17 +1,20 @@
-def gen_reaper_results(this_trait, dataset, samples_before, json_data, num_perm, bootCheck, num_bootstrap, do_control, control_marker, manhattan_plot):
+import utility.logger
+logger = utility.logger.getLogger(__name__ )
+
+def gen_reaper_results(this_trait, dataset, samples_before, trait_vals, json_data, num_perm, bootCheck, num_bootstrap, do_control, control_marker, manhattan_plot):
     genotype = dataset.group.read_genotype_file()
 
     if manhattan_plot != True:
         genotype = genotype.addinterval()
 
-    samples, values, variances, sample_aliases = this_trait.export_informative()
-
     trimmed_samples = []
     trimmed_values = []
-    for i in range(0, len(samples)):
-        if this_trait.data[samples[i]].name in samples_before:
-            trimmed_samples.append(samples[i])
-            trimmed_values.append(values[i])
+    for i in range(0, len(samples_before)):
+        try:
+            trimmed_values.append(float(trait_vals[i]))
+            trimmed_samples.append(samples_before[i])
+        except:
+            pass
 
     perm_output = []
     bootstrap_results = []
diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py
index 59e100d8..53c96591 100644
--- a/wqflask/wqflask/search_results.py
+++ b/wqflask/wqflask/search_results.py
@@ -10,6 +10,7 @@ import time
 import math
 import datetime
 import collections
+import re
 
 from pprint import pformat as pf
 
@@ -25,6 +26,7 @@ from db import webqtlDatabaseFunction
 from flask import render_template
 
 from utility import formatting
+from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string
 
 from utility.logger import getLogger
 logger = getLogger(__name__ )
@@ -64,14 +66,26 @@ views.py).
         else:
             self.and_or = "and"
             self.search_terms = kw['search_terms_and']
-        self.search_term_exists = True
+        search = self.search_terms
+        # check for dodgy search terms
+        rx = re.compile(r'.*\W(href|http|sql|select|update)\W.*',re.IGNORECASE)
+        if rx.match(search):
+            logger.info("Regex failed search")
+            self.search_term_exists = False
+            return
+        else:
+            self.search_term_exists = True
+
         self.results = []
-        if kw['type'] == "Phenotypes":     # split datatype on type field
+        type = kw.get('type')
+        if type == "Phenotypes":     # split datatype on type field
             dataset_type = "Publish"
-        elif kw['type'] == "Genotypes":
+        elif type == "Genotypes":
             dataset_type = "Geno"
         else:
             dataset_type = "ProbeSet"      # ProbeSet is default
+
+        assert(is_str(kw.get('dataset')))
         self.dataset = create_dataset(kw['dataset'], dataset_type)
         logger.debug("search_terms:", self.search_terms)
         self.search()
@@ -145,6 +159,7 @@ statement and executes
                         else:
                             combined_where_clause += "OR"
                 else:
+                    logger.debug("Search failed 1")
                     self.search_term_exists = False
             if self.search_term_exists:
                 combined_where_clause = "(" + combined_where_clause + ")"
@@ -155,6 +170,7 @@ statement and executes
         else:
             logger.debug("len(search_terms)<=1")
             if self.search_terms == []:
+                logger.debug("Search failed 2")
                 self.search_term_exists = False
             else:
                 for a_search in self.search_terms:
@@ -162,6 +178,7 @@ statement and executes
                     if the_search != None:
                         self.results.extend(the_search.run())
                     else:
+                        logger.debug("Search failed 3")
                         self.search_term_exists = False
 
         if self.search_term_exists:
diff --git a/wqflask/wqflask/static/dbdoc/TODO.md b/wqflask/wqflask/static/dbdoc/TODO.md
new file mode 100644
index 00000000..c0a8bab7
--- /dev/null
+++ b/wqflask/wqflask/static/dbdoc/TODO.md
@@ -0,0 +1 @@
+TODO: Add all database documentation into this folder
diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js
index 43ac6086..bf0a14e6 100644
--- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js
+++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js
@@ -1,6 +1,7 @@
 var chart;
+var srchart;
 
-function drawg () {
+function drawg() {
     //
     chart = nv.models.scatterChart();
     //
@@ -27,11 +28,45 @@ function drawg () {
     chart.yAxis.tickFormat(d3.format(checkformat(yrange)));
     //
     chart.tooltip.contentGenerator(function (obj) {
-        // return '<b style="font-size: 18px">(' + obj.point.x + ', ' + obj.point.y + ')</b>';
-        return '<b style="font-size: 18px">' + obj.point.name + '</b>';
+        return tiptext(obj);
     });
 }
 
+function srdrawg() {
+    //
+    srchart = nv.models.scatterChart();
+    //
+    srchart.showLegend(false);
+    srchart.duration(300);
+    srchart.color(d3.scale.category10().range());
+    srchart.pointRange([0, 400]);
+    srchart.pointDomain([0, 10]);
+    //
+    srchart.xAxis.axisLabel(js_data.trait_1);
+    srchart.xAxis.axisLabelDistance(11);
+    srchart.yAxis.axisLabel(js_data.trait_2);
+    srchart.yAxis.axisLabelDistance(11);
+    //
+    xmin = d3.min(js_data.rdata[0]);
+    xmax = d3.max(js_data.rdata[0]);
+    xrange = xmax - xmin;
+    ymin = d3.min(js_data.rdata[1]);
+    ymax = d3.max(js_data.rdata[1]);
+    yrange = ymax - ymin;
+    srchart.xDomain([0, xmax + xrange/10]);
+    srchart.yDomain([0, ymax + yrange/10]);
+    srchart.xAxis.tickFormat(d3.format(checkformat(xrange)));
+    srchart.yAxis.tickFormat(d3.format(checkformat(yrange)));
+    //
+    srchart.tooltip.contentGenerator(function (obj) {
+        return tiptext(obj);
+    });
+}
+
+function tiptext(obj) {
+    return '<b style="font-size: 18px">' + obj.point.name + " (" + obj.point.x + ', ' + obj.point.y + ')</b>';
+}
+
 function getdata(size, shape) {
     var data = [];
     data.push({
@@ -50,6 +85,25 @@ function getdata(size, shape) {
     }
     return data;
 }
+
+function srgetdata(size, shape) {
+    var data = [];
+    data.push({
+            values: [],
+            slope: js_data.srslope,
+            intercept: js_data.srintercept
+        });
+    for (j = 0; j < js_data.rdata[0].length; j++) {
+        data[0].values.push({
+            x: js_data.rdata[0][j],
+            y: js_data.rdata[1][j],
+            name: js_data.indIDs[j],
+            size: size,
+            shape: shape
+        });
+    }
+    return data;
+}
     
 function checkformat(range) {
     cell = range / 10.0;
@@ -64,50 +118,47 @@ function checkformat(range) {
 
 function chartupdate() {
     //
-    var axisxcolor = $("#axisxcolor").val();
-    $(".nvd3 .nv-axis.nv-x text").css("fill", axisxcolor);
+    var labelcolor = $("#labelcolor").val();
+    $(".nvd3 .nv-axis.nv-x text").css("fill", labelcolor);
+    $(".nvd3 .nv-axis.nv-y text").css("fill", labelcolor);
     //
-    var axisycolor = $("#axisycolor").val();
-    $(".nvd3 .nv-axis.nv-y text").css("fill", axisycolor);
+    var labelfont = $("#labelfont").val();
+    $(".nvd3 .nv-axis.nv-x text").css("font-size", labelfont);
+    $(".nvd3 .nv-axis.nv-y text").css("font-size", labelfont);
     //
-    var axisxfont = $("#axisxfont").val();
-    $(".nvd3 .nv-axis.nv-x text").css("font-size", axisxfont);
+    var numbercolor = $("#numbercolor").val();
+    $("g.tick text").css("fill", numbercolor);
     //
-    var axisyfont = $("#axisyfont").val();
-    $(".nvd3 .nv-axis.nv-y text").css("font-size", axisyfont);
+    var numberfont = $("#numberfont").val();
+    $("g.tick text").css("font-size", numberfont);
     //
-    var domainxcolor = $("#domainxcolor").val();
-    $(".nv-x .nv-axis g path.domain").css("stroke", domainxcolor);
-    //
-    var domainycolor = $("#domainycolor").val();
-    $(".nv-y .nv-axis g path.domain").css("stroke", domainycolor);
-    //
-    var domainxwidth = $("#domainxwidth").val();
-    $(".nv-x .nv-axis g path.domain").css("stroke-width", domainxwidth);
+    var axiscolor = $("#axiscolor").val();
+    $(".nv-x .nv-axis g path.domain").css("stroke", axiscolor);
+    $(".nv-y .nv-axis g path.domain").css("stroke", axiscolor);
     //
-    var domainywidth = $("#domainywidth").val();
-    $(".nv-y .nv-axis g path.domain").css("stroke-width", domainywidth);
+    var axiswidth = $("#axiswidth").val();
+    $(".nv-x .nv-axis g path.domain").css("stroke-width", axiswidth);
+    $(".nv-y .nv-axis g path.domain").css("stroke-width", axiswidth);
     //
-    var clinecolor = $("#clinecolor").val();
-    $("line.nv-regLine").css("stroke", clinecolor);
+    var linecolor = $("#linecolor").val();
+    $("line.nv-regLine").css("stroke", linecolor);
     //
-    var clinewidth = $("#clinewidth").val();
-    $("line.nv-regLine").css("stroke-width", clinewidth);
+    var linewidth = $("#linewidth").val();
+    $("line.nv-regLine").css("stroke-width", linewidth);
     //
-    var axiscolor = $("#axiscolor").val();
-    $(".tick").css("stroke", axiscolor);
-    //
-    var axiswidth = $("#axiswidth").val();
-    $("line.nv-regLine").css("stroke-width", axiswidth); 
+    var markcolor = $("#markcolor").val();
+    $(".nvd3 g path").css("fill", markcolor);
 }
 
 function chartupdatewh() {
     //
     var width = $("#width").val();
     $("#scatterplot2 svg").css("width", width);
+    $("#srscatterplot2 svg").css("width", width);
     //
     var height = $("#height").val();
     $("#scatterplot2 svg").css("height", height);
+    $("#srscatterplot2 svg").css("height", height);
     //
     window.dispatchEvent(new Event('resize'));
 }
@@ -118,7 +169,9 @@ function chartupdatedata() {
     var shape = $("#markshape").val();
     //
     d3.select('#scatterplot2 svg').datum(nv.log(getdata(size, shape))).call(chart);
+    d3.select('#srscatterplot2 svg').datum(nv.log(srgetdata(size, shape))).call(srchart);
     nv.utils.windowResize(chart.update);
+    nv.utils.windowResize(srchart.update);
 }
 
 function savesvg(svgEl, name) {
@@ -140,10 +193,14 @@ function saveassvg_pcs() {
     savesvg($("#svg_pcs")[0], "Pearson Correlation Scatterplot.svg");
 }
 
+function saveassvg_srcs() {
+    savesvg($("#svg_srcs")[0], "Spearman Rank Correlation Scatterplot.svg");
+}
+
 drawg();
-chartupdate();
-chartupdatewh();
-chartupdatedata();
+srdrawg();
+
+
 
 $(".chartupdate").change(function () {
     chartupdate();
@@ -156,3 +213,10 @@ $(".chartupdatewh").change(function () {
 $(".chartupdatedata").change(function () {
     chartupdatedata();
 });
+
+$(document).ready(function(){
+    //chartupdate();
+//chartupdatewh();
+chartupdatedata();
+//chartupdate();
+});
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js
deleted file mode 100644
index d0392dd7..00000000
--- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js
+++ /dev/null
@@ -1,137 +0,0 @@
-var srchart;
-
-function srdrawg () {
-    //
-    srchart = nv.models.scatterChart();
-    //
-    srchart.showLegend(false);
-    srchart.duration(300);
-    srchart.color(d3.scale.category10().range());
-    srchart.pointRange([0, 400]);
-    srchart.pointDomain([0, 10]);
-    //
-    srchart.xAxis.axisLabel(js_data.trait_1);
-    srchart.xAxis.axisLabelDistance(11);
-    srchart.yAxis.axisLabel(js_data.trait_2);
-    srchart.yAxis.axisLabelDistance(11);
-    //
-    xmin = d3.min(js_data.rdata[0]);
-    xmax = d3.max(js_data.rdata[0]);
-    xrange = xmax - xmin;
-    ymin = d3.min(js_data.rdata[1]);
-    ymax = d3.max(js_data.rdata[1]);
-    yrange = ymax - ymin;
-    srchart.xDomain([0, xmax + xrange/10]);
-    srchart.yDomain([0, ymax + yrange/10]);
-    srchart.xAxis.tickFormat(d3.format(srcheckformat(xrange)));
-    srchart.yAxis.tickFormat(d3.format(srcheckformat(yrange)));
-    //
-    srchart.tooltip.contentGenerator(function (obj) {
-        // return '<b style="font-size: 18px">(' + obj.point.x + ', ' + obj.point.y + ')</b>';
-        return '<b style="font-size: 18px">' + obj.point.name + '</b>';
-    });
-}
-
-function srgetdata(size, shape) {
-    var data = [];
-    data.push({
-            values: [],
-            slope: js_data.srslope,
-            intercept: js_data.srintercept
-        });
-    for (j = 0; j < js_data.rdata[0].length; j++) {
-        data[0].values.push({
-            x: js_data.rdata[0][j],
-            y: js_data.rdata[1][j],
-            name: js_data.indIDs[j],
-            size: size,
-            shape: shape
-        });
-    }
-    return data;
-}
-    
-function srcheckformat(range) {
-    cell = range / 10.0;
-    if (cell >= 1) {
-        return ",r";
-    } else {
-        cell = -Math.log(cell);
-        n = cell.toString().split(".")[0].length;
-        return ",.0" + n + "f";
-    }
-}
-
-function srchartupdate() {
-    //
-    var axisxcolor = $("#axisxcolor").val();
-    $(".nvd3 .nv-axis.nv-x text").css("fill", axisxcolor);
-    //
-    var axisycolor = $("#axisycolor").val();
-    $(".nvd3 .nv-axis.nv-y text").css("fill", axisycolor);
-    //
-    var axisxfont = $("#axisxfont").val();
-    $(".nvd3 .nv-axis.nv-x text").css("font-size", axisxfont);
-    //
-    var axisyfont = $("#axisyfont").val();
-    $(".nvd3 .nv-axis.nv-y text").css("font-size", axisyfont);
-    //
-    var domainxcolor = $("#domainxcolor").val();
-    $(".nv-x .nv-axis g path.domain").css("stroke", domainxcolor);
-    //
-    var domainycolor = $("#domainycolor").val();
-    $(".nv-y .nv-axis g path.domain").css("stroke", domainycolor);
-    //
-    var domainxwidth = $("#domainxwidth").val();
-    $(".nv-x .nv-axis g path.domain").css("stroke-width", domainxwidth);
-    //
-    var domainywidth = $("#domainywidth").val();
-    $(".nv-y .nv-axis g path.domain").css("stroke-width", domainywidth);
-    //
-    var clinecolor = $("#clinecolor").val();
-    $("line.nv-regLine").css("stroke", clinecolor);
-    //
-    var clinewidth = $("#clinewidth").val();
-    $("line.nv-regLine").css("stroke-width", clinewidth);
-}
-
-function srchartupdatewh() {
-    //
-    var width = $("#srwidth").val();
-    $("#srscatterplot2 svg").css("width", width);
-    //
-    var height = $("#srheight").val();
-    $("#srscatterplot2 svg").css("height", height);
-    //
-    window.dispatchEvent(new Event('resize'));
-}
-
-function srchartupdatedata() {
-    //
-    var size = $("#srmarksize").val();
-    var shape = $("#srmarkshape").val();
-    //
-    d3.select('#srscatterplot2 svg').datum(nv.log(srgetdata(size, shape))).call(srchart);
-    nv.utils.windowResize(srchart.update);
-}
-
-function saveassvg_srcs() {
-    savesvg($("#svg_srcs")[0], "Spearman Rank Correlation Scatterplot.svg");
-}
-
-srdrawg();
-srchartupdate();
-srchartupdatewh();
-srchartupdatedata();
-
-$(".srchartupdate").change(function () {
-    srchartupdate();
-});
-
-$(".srchartupdatewh").change(function () {
-    srchartupdatewh();
-});
-
-$(".srchartupdatedata").change(function () {
-    srchartupdatedata();
-});
diff --git a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
index 92e2b13b..f2e694d8 100644
--- a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
+++ b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
@@ -24,6 +24,7 @@ collection_click = function() {
 
 submit_click = function() {
   var covariates_string = "";
+  var covariates_display_string = "";
   $('#collections_holder').find('input[type=checkbox]:checked').each(function() {
     var this_dataset, this_trait;
     this_trait = $(this).parents('tr').find('.trait').text();
@@ -31,12 +32,15 @@ submit_click = function() {
     this_dataset = $(this).parents('tr').find('.dataset').text();
     console.log("this_dataset is:", this_dataset);
     covariates_string += this_trait + ":" + this_dataset + ","
+    covariates_display_string += this_trait + "\n"
   });
   // Trim the last comma
   covariates_string = covariates_string.substring(0, covariates_string.length - 1)
+  //covariates_display_string = covariates_display_string.substring(0, covariates_display_string.length - 2)
   console.log("COVARIATES:", covariates_string)
 
   $("input[name=covariates]").val(covariates_string)
+  $(".selected_covariates").val(covariates_display_string)
 
   return $.colorbox.close();
 };
@@ -46,6 +50,7 @@ trait_click = function() {
   trait = $(this).parent().find('.trait').text();
   dataset = $(this).parent().find('.dataset').text();
   $("input[name=covariates]").val(trait + ":" + dataset)
+  $(".selected_covariates").text(trait)
   return $.colorbox.close();
 };
 
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js
index 099d8010..df10c060 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait.js
@@ -88,7 +88,8 @@
       };
     })(this));
     $("#remove_covariates").click(function () {
-        $("input[name=covariates]").val("") 
+        $("input[name=covariates]").val("")
+        $(".selected_covariates").val("")
     });
     d3.select("#clear_compare_trait").on("click", (function(_this) {
       return function() {
diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html
index ad72052e..e7f3229b 100644
--- a/wqflask/wqflask/templates/collections/list.html
+++ b/wqflask/wqflask/templates/collections/list.html
@@ -26,13 +26,13 @@
             {% endif %}
         </div>
         <div>
-          <form id="collections_form" action="/delete" method="post">
-            <input type="hidden" name="uc_id" id="uc_id" value="" />
-          </form>
+            <form id="collections_form" action="/delete" method="post">
+              <input type="hidden" name="uc_id" id="uc_id" value="" />
+            </form>
             <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
             <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
             <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
-            <button class="btn btn-danger" id="remove_collections" data-url="/collections/delete">Remove Collections</button> 
+            <button class="btn btn-danger" id="remove_collections" data-url="/collections/delete">Remove Collections</button>
         </div>
         <br>
         <div id="collections_list" style="width:50%;">
@@ -51,7 +51,11 @@
             <tbody>
             {% for uc in collections %}
                 <tr class="collection_line">
+                    {% if g.user_session.user_ob %}
                     <td style="padding-left: 8px; padding-right: 0px; padding-top: 4px; align: center;"><INPUT TYPE="checkbox" NAME="collection" class="checkbox trait_checkbox" VALUE="{{ uc.id }}"></td>
+                    {% else %}
+                    <td style="padding-left: 8px; padding-right: 0px; padding-top: 4px; align: center;"><INPUT TYPE="checkbox" NAME="collection" class="checkbox trait_checkbox" VALUE="{{ uc.name }}"></td>
+                    {% endif %}
                     <td align="right">{{ loop.index }}
                     {% if g.user_session.user_ob %}
                     <td><a class="collection_name" href="{{ url_for('view_collection', uc_id=uc.id) }}">{{ uc.name }}</a></td>
diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html
index fb2bd55c..bb509270 100644
--- a/wqflask/wqflask/templates/corr_scatterplot.html
+++ b/wqflask/wqflask/templates/corr_scatterplot.html
@@ -75,72 +75,16 @@
 

 <table class="table">

 	<tr>

-    

-        <td>Axis X Color</td>

-		<td><input class="chartupdate" id="axisxcolor" type="color" value="#000000"></td>

-        

-        <td>Axis X Font</td>

-		<td><input class="chartupdate" id="axisxfont" type="text" value="16" style="width: 44px;"> px</td>

-        

-        <td>Domain X Color</td>

-		<td><input class="chartupdate" id="domainxcolor" type="color" value="#000000"></td>

-        

-        <td>Domain X Width</td>

-		<td><input class="chartupdate" id="domainxwidth" type="text" value="2" style="width: 44px;"> px</td>

-        

-        <td>Correlation Line Color</td>

-		<td><input class="chartupdate" id="clinecolor" type="color" value="#000000"></td>

-        

-        <td>Axis Line Color</td>

-		<td><input class="chartupdate" id="axiscolor" type="color" value="#000000"></td>

-        

-	</tr>

-	<tr>

-    

-        <td>Axis Y Color</td>

-		<td><input class="chartupdate" id="axisycolor" type="color" value="#000000"></td>

-        

-        <td>Axis Y Font</td>

-		<td><input class="chartupdate" id="axisyfont" type="text" value="16" style="width: 44px;"> px</td>

-        

-        <td>Domain Y Color</td>

-		<td><input class="chartupdate" id="domainycolor" type="color" value="#000000"></td>

-        

-        <td>Domain Y Width</td>

-		<td><input class="chartupdate" id="domainywidth" type="text" value="2" style="width: 44px;"> px</td>

-        

-        <td>Correlation Line Width</td>

-		<td><input class="chartupdate" id="clinewidth" type="text" value="1" style="width: 44px;"> px</td>

-        

-        <td>Axis Line Width</td>

-		<td><input class="chartupdate" id="axiswidth" type="text" value="1" style="width: 44px;"> px</td>

-        

-	</tr>

+        <td style="vertical-align: middle;">Width <input class="chartupdatewh" id="width" type="text" value="1000" style="width: 44px; height: 22px;"> px</td>

+        <td style="vertical-align: middle;">Height <input class="chartupdatewh" id="height" type="text" value="800" style="width: 44px; height: 22px;"> px</td>

+    </tr>

 </table>

 

-<br>

-

-<ul class="nav nav-tabs">

-    <li class="active"><a href="#tp1" data-toggle="tab">Pearson</a></li>

-    <li>               <a href="#tp2" data-toggle="tab">Spearman Rank</a></li>

-</ul>

-

-<div class="tab-content">

-    <div class="tab-pane active" id="tp1">

-

-<br>

 <table class="table">

-	<tr>

-    

-        <td>Width</td>

-		<td><input class="chartupdatewh" id="width" type="text" value="1000" style="width: 44px;"> px</td>

-    

-        <td>Height</td>

-		<td><input class="chartupdatewh" id="height" type="text" value="800" style="width: 44px;"> px</td>

-        

-		<td>Size</td>

-		<td>

-            <select class="chartupdatedata" id="marksize" style="width: 100px;">

+    <tr>

+		<td style="vertical-align: middle;">Mark

+            <input class="chartupdate" id="markcolor" type="color" value="#8fbbda">

+            <select class="chartupdatedata" id="marksize" style="width: 44px; height: 22px;">

                 <option value="0">0</option>

                 <option value="1">1</option>

                 <option value="2">2</option>

@@ -152,12 +96,12 @@
                 <option value="8">8</option>

                 <option value="9">9</option>

                 <option value="10">10</option>

+                <option value="15">15</option>

+                <option value="20">20</option>

+                <option value="25">25</option>

+                <option value="30">30</option>

             </select>

-        </td>

-	

-		<td>Shape</td>

-		<td>

-            <select class="chartupdatedata" id="markshape" style="width: 100px;">

+            <select class="chartupdatedata" id="markshape" style="width: 100px; height: 22px;">

                 <option value="circle" selected>Circle</option>

                 <option value="cross">Cross</option>

                 <option value="triangle-up">Triangle-up</option>

@@ -166,23 +110,47 @@
                 <option value="square">Square</option>

             </select>

         </td>

-        

-	</tr>

+    </tr>

 </table>

 

-<div><a id="a_svg_pcs" href="#" onclick="javascript:saveassvg_pcs();" class="btn btn-primary">Save as SVG</a></div>

+<table class="table">    

+    <tr>

+        <td style="vertical-align: middle;">Label

+            <input class="chartupdate" id="labelcolor" type="color" value="#000000">

+            <input class="chartupdate" id="labelfont" type="text" value="16" style="width: 44px; height: 22px;"> px

+        </td>

+        <td style="vertical-align: middle;">Number

+            <input class="chartupdate" id="numbercolor" type="color" value="#000000">

+            <input class="chartupdate" id="numberfont" type="text" value="16" style="width: 44px; height: 22px;"> px

+        </td>

+        <td style="vertical-align: middle;">Axis

+            <input class="chartupdate" id="axiscolor" type="color" value="#000000">

+            <input class="chartupdate" id="axiswidth" type="text" value="2" style="width: 44px; height: 22px;"> px

+        </td>

+        <td style="vertical-align: middle;">Line

+            <input class="chartupdate" id="linecolor" type="color" value="#8fbbda">

+            <input class="chartupdate" id="linewidth" type="text" value="1" style="width: 44px; height: 22px;"> px

+        </td>

+    </tr>

+</table>

 

-<div style="width: 1000px; text-align: center;"><h2>Pearson Correlation Scatterplot</h2></div>

+<br>

 

-<div id="scatterplot2">

-	<svg id="svg_pcs" style="width: 1000px; height: 800px; margin-left: 10px;"></svg>

-</div>

+<ul class="nav nav-tabs">

+    <li class="active"><a href="#tp1" data-toggle="tab">Pearson</a></li>

+    <li>               <a href="#tp2" data-toggle="tab">Spearman Rank</a></li>

+</ul>

+

+<div class="tab-content">

+    <div class="tab-pane active" id="tp1">

 

 <br>

 

-<div class="alert alert-info" style="width: 200px; margin-left: 80px;">

-    y = {{'%0.3f' % jsdata.slope}} * x + {{'%0.3f' % jsdata.intercept}}

-</div>

+<div><a id="a_svg_pcs" href="#" onclick="javascript:saveassvg_pcs();" class="btn btn-primary">Save as SVG</a></div>

+

+<div style="width: 1000px; text-align: center;"><h2>Pearson Correlation Scatterplot</h2></div>

+

+<div id="scatterplot2"><svg id="svg_pcs" style="width: 1000px; height: 800px; margin-left: 10px;"></svg></div>

 

 <br>

 

@@ -196,6 +164,13 @@
 		<tr><td>Intercept</td>	<td>{{'%0.3f' % jsdata.intercept}}</td></tr>

 		<tr><td>r value</td>	<td>{{'%0.3f' % jsdata.r_value}}</td></tr>

    		<tr><td>P value</td>	<td>{% if jsdata.p_value < 0.001 %}{{'%0.3e' % jsdata.p_value}}{% else %}{{'%0.3f' % jsdata.p_value}}{% endif %}</td></tr>

+        <tr>

+            <td style="text-align: left;" colspan="2">

+                Regression Line

+                <br>

+                y = {{'%0.3f' % jsdata.slope}} * x + {{'%0.3f' % jsdata.intercept}}

+            </td>

+        </tr>

 	</tbody>

 </table>

 

@@ -204,54 +179,12 @@
     <div class="tab-pane" id="tp2">

     

 <br>

-<table class="table">

-	<tr>

-    

-        <td>Width</td>

-		<td><input class="srchartupdatewh" id="srwidth" type="text" value="1000" style="width: 44px;"> px</td>

-    

-        <td>Height</td>

-		<td><input class="srchartupdatewh" id="srheight" type="text" value="800" style="width: 44px;"> px</td>

-        

-		<td>Size</td>

-		<td>

-            <select class="srchartupdatedata" id="srmarksize" style="width: 100px;">

-                <option value="0">0</option>

-                <option value="1">1</option>

-                <option value="2">2</option>

-                <option value="3">3</option>

-                <option value="4">4</option>

-                <option value="5" selected>5</option>

-                <option value="6">6</option>

-                <option value="7">7</option>

-                <option value="8">8</option>

-                <option value="9">9</option>

-                <option value="10">10</option>

-            </select>

-        </td>

-    

-		<td>Shape</td>

-		<td>

-            <select class="srchartupdatedata" id="srmarkshape" style="width: 100px;">

-                <option value="circle" selected>Circle</option>

-                <option value="cross">Cross</option>

-                <option value="triangle-up">Triangle-up</option>

-                <option value="triangle-down">Triangle-down</option>

-                <option value="diamond">Diamond</option>

-                <option value="square">Square</option>

-            </select>

-        </td>

-        

-	</tr>

-</table>

 

 <div><a id="a_svg_srcs" href="#" onclick="javascript:saveassvg_srcs();" class="btn btn-primary">Save as SVG</a></div>

 

 <div style="width: 1000px; text-align: center;"><h2>Spearman Rank Correlation Scatterplot</h2></div>

 

-<div id="srscatterplot2">

-	<svg id="svg_srcs" style="width: 1000px; height: 800px; margin-left: 10px;"></svg>

-</div>

+<div id="srscatterplot2"><svg id="svg_srcs" style="width: 1000px; height: 800px; margin-left: 10px;"></svg></div>

 

 <br>

 

@@ -287,5 +220,4 @@
     <script language="javascript" type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script>

     <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>

     <script language="javascript" type="text/javascript" src="/static/new/javascript/draw_corr_scatterplot-2.js"></script>

-    <script language="javascript" type="text/javascript" src="/static/new/javascript/draw_corr_scatterplot-2_sr.js"></script>

 {% endblock %}

diff --git a/wqflask/wqflask/templates/correlation_matrix.html b/wqflask/wqflask/templates/correlation_matrix.html
index ab793d58..d27788a8 100644
--- a/wqflask/wqflask/templates/correlation_matrix.html
+++ b/wqflask/wqflask/templates/correlation_matrix.html
@@ -61,6 +61,7 @@
 <br>
 <button class="btn btn-default" id="short_labels">Short Labels</button>
 <button class="btn btn-default" id="long_labels">Long Labels</button>
+{% if pca_works == "True" %}
 <br>
 <br>
 <h2>Factor Loadings Plot</h2>
@@ -93,7 +94,7 @@
   </tbody>
 </table>
 </div>
-
+{% endif %}
 {% endblock %}
 
 {% block js %}
diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html
index fa9e3585..fb4e19a1 100644
--- a/wqflask/wqflask/templates/correlation_page.html
+++ b/wqflask/wqflask/templates/correlation_page.html
@@ -1,8 +1,7 @@
 {% extends "base.html" %}
 {% block css %}
+    <link rel="stylesheet" type="text/css" href="/static/new/packages/tabulator/css/tabulator.css" />
     <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
-    <link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
-    <link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />
     <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/buttons.bootstrap.css" />
 {% endblock %}
 {% block content %}
@@ -63,15 +62,15 @@
         </div>
 
         <div style="width: {% if target_dataset.type == "ProbeSet" %}1600px{% elif target_dataset.type == "Publish" %}1400px{% else %}800px{% endif %};">
-            <table id="trait_table" class="display dataTable nowrap" style="float: left;">
+            <table id="trait_table" class="display dataTable nowrap" style="font-size: 12px; float: left;">
                 <thead>
                     <tr>
-                        <th style="width: 30px;"></th>
+                        <th></th>
                     {% for header in target_dataset.header_fields %}
                         {% if header == 'Year' %}
                         <th>{{header}}</th>
                         {% elif header == 'Max LRS' %}
-                        <th>Max LRS<a href="http://genenetwork.org//glossary.html#L" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
+                        <th>Max LRS</th>
                         {% elif header == 'Max LRS Location' %}
                         <th>{{header}}</th>
                         {% elif header == 'Location' %}
@@ -79,7 +78,7 @@
                         {% elif header == 'Mean' %}
                         <th>{{header}}</th>
                         {% elif header == 'Additive Effect' %}
-                        <th>Additive Effect<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
+                        <th>Additive Effect</th>
                         {% elif header == 'Index' %}
                         <th>{{header}}</th>
                         {% elif header == 'N' %}
@@ -91,7 +90,7 @@
                     {% if target_dataset.type == "ProbeSet" %}
                         {% if corr_method == 'pearson' %}
                         <th>Sample r</th>
-                        <th>&nbsp;&nbsp;N</th>
+                        <th>N</th>
                         <th>Sample p(r)</th>
                         <th>Lit r</th>
                         <th>Tissue r</th>
@@ -129,8 +128,8 @@
                 <tbody>
                 {% for trait in correlation_results %}
                     <tr>
-                        <td style="padding-left: 8px; padding-right: 0px; padding-top: 4px; align: center;"><INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox" style="padding-right: 0px;" VALUE="{{ data_hmac('{}:{}'.format(trait.name, trait.dataset.name)) }}"></td>
-                        <td align="right">{{ loop.index }}</td>
+                        <td><INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox" style="padding-right: 0px;" VALUE="{{ data_hmac('{}:{}'.format(trait.name, trait.dataset.name)) }}"></td>
+                        <td style="padding-left: 8px; padding-right: 0px; padding-top: 4px; align: center;">{{ loop.index }}</td>
                         <td>
                             <a href="{{ url_for('show_trait_page',
                                     trait_id = trait.name,
@@ -191,13 +190,15 @@
 {% block js %}  
     <script type="text/javascript" src="/static/new/javascript/search_results.js"></script>
 
+    <script language="javascript" type="text/javascript" src="/static/new/js_external/jszip.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/packages/DataTables/js/jquery.dataTables.js"></script>
     <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/dataTables.buttons.min.js"></script>
     <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/buttons.html5.min.js"></script>
     <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/buttons.bootstrap.min.js"></script>
-    <script language="javascript" type="text/javascript" src="/static/new/js_external/jszip.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/underscore/underscore-min.js"></script>
+
     <script type="text/javascript" charset="utf-8">
         function getValue(x) {
             if (x.indexOf('input') >= 0) {
@@ -213,7 +214,8 @@
             }
             return parseFloat(x);
         }
-            
+
+
         jQuery.fn.dataTableExt.oSort['numeric-html-asc']  = function(a,b) {
             a = Math.abs(parseFloat($(a).text()));
             b = Math.abs(parseFloat($(b).text()));
@@ -263,6 +265,8 @@
 
         $(document).ready( function () {
             
+            var table_json = {{ json_results | safe }}
+
             $('#trait_table tr').click(function(event) {
                 if (event.target.type !== 'checkbox') {
                     $(':checkbox', this).trigger('click');
diff --git a/wqflask/wqflask/templates/empty_collection.html b/wqflask/wqflask/templates/empty_collection.html
new file mode 100644
index 00000000..d1b779ef
--- /dev/null
+++ b/wqflask/wqflask/templates/empty_collection.html
@@ -0,0 +1,15 @@
+{% extends "base.html" %}
+{% block title %}{{ tool }}{% endblock %}
+{% block content %}
+<!-- Start of body -->
+    {{ header("Error") }}
+
+    <div class="container">
+        <input type="hidden" name="uc_id" id="uc_id" value="{{ uc_id }}">
+        <p>You must select at least two traits to use the {{ tool }}.</p>
+    </div>
+
+
+<!-- End of body -->
+
+{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html
index 0dae3503..949760b6 100644
--- a/wqflask/wqflask/templates/new_security/login_user.html
+++ b/wqflask/wqflask/templates/new_security/login_user.html
@@ -15,7 +15,6 @@
 
             <h4>Don't have an account?</h4>
 
-
             {% if es_server: %}
 	    <a href="/n/register" class="btn btn-primary modalize">Create a new account</a>
 	    {% else: %}
@@ -88,10 +87,17 @@
             </form>
 	    {% else: %}
 	    <div class="alert alert-warning">
-	      <p>You cannot login at this moment using your GeneNetwork account.<br />
+	      <p>You cannot login at this moment using your GeneNetwork account (the authentication service is down).<br />
 		Please try again later.</p>
 	    </div>
 	    {% endif %}
+            {% if not es_server and not external_login: %}
+            <hr>
+	    <div class="alert alert-warning">
+               Note: it is safe to use GeneNetwork without a login. Login is only required for keeping track of
+            collections and getting access to some types of restricted data.
+            </div>
+            {% endif %}
         </div>
     </div>
 
diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html
index c5f815ce..ef233333 100644
--- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html
+++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html
@@ -1,9 +1,10 @@
 <div>
+  <div class="col-xs-7">
     <div style="padding: 20px" class="form-horizontal">
         
         <div class="form-group">
-            <label for="corr_type" class="col-xs-1 control-label">Method</label>
-            <div class="col-xs-2 controls">
+            <label for="corr_type" class="col-xs-2 control-label">Method</label>
+            <div class="col-xs-3 controls">
                 <select name="corr_type" class="form-control">
                     <option value="sample">Sample r</option>
                     <option value="lit">Literature r</option>
@@ -13,8 +14,8 @@
         </div>
         
         <div class="form-group">
-            <label for="corr_dataset" class="col-xs-1 control-label">Database</label>
-            <div class="col-xs-6 controls">
+            <label for="corr_dataset" class="col-xs-2 control-label">Database</label>
+            <div class="col-xs-10 controls">
                 <select name="corr_dataset" class="form-control">
                     {% for tissue in corr_tools.dataset_menu %}
                         {% if tissue.tissue %}
@@ -37,8 +38,8 @@
         </div>
         
         <div class="form-group">
-            <label for="corr_return_results" class="col-xs-1 control-label">Return</label>
-            <div class="col-xs-2 controls">
+            <label for="corr_return_results" class="col-xs-2 control-label">Return</label>
+            <div class="col-xs-3 controls">
                 <select name="corr_return_results" class="form-control">
                     {% for return_result in corr_tools.return_results_menu %}
                         <option value="{{ return_result }}" 
@@ -53,8 +54,8 @@
         </div>
         
         <div class="form-group">
-            <label for="corr_samples_group" class="col-xs-1 control-label">Samples</label>
-            <div class="col-xs-2 controls">
+            <label for="corr_samples_group" class="col-xs-2 control-label">Samples</label>
+            <div class="col-xs-3 controls">
                 <select name="corr_samples_group" class="form-control">
                     {% for group, pretty_group in sample_group_types.items() %}
                         <option value="{{ group }}">{{ pretty_group }}</option>
@@ -64,8 +65,8 @@
         </div>
             
         <div id="corr_sample_method" class="form-group">
-            <label for="corr_sample_method" class="col-xs-1 control-label">Type</label>
-            <div class="col-xs-2 controls">
+            <label for="corr_sample_method" class="col-xs-2 control-label">Type</label>
+            <div class="col-xs-3 controls">
                 <select name="corr_sample_method" class="form-control">
                     <option value="pearson">Pearson</option>
                     <option value="spearman">Spearman Rank</option>
@@ -73,14 +74,14 @@
             </div>
         </div>
         <div class="form-group">
-            <label class="col-xs-1 control-label">Min Expr</label>
-            <div class="col-xs-2 controls">
+            <label class="col-xs-2 control-label">Min Expr</label>
+            <div class="col-xs-3 controls">
                 <input name="min_expr" value="" type="text" class="form-control" style="width: 50px;">
             </div>
         </div>
         <div class="form-group">
-            <label class="col-xs-1 control-label">Location</label>
-            <div class="col-xs-4 controls">
+            <label class="col-xs-2 control-label">Location</label>
+            <div class="col-xs-5 controls">
                 <span>
                 Chr: <input name="loc_chr" value="" type="text" class="form-control" style="width: 50px; display: inline;">&nbsp;&nbsp;&nbsp;
                 Mb: <input name="min_loc_mb" value="" type="text" class="form-control" style="width: 50px; display: inline;"> &nbsp;to&nbsp; <input name="max_loc_mb" value="" type="text" class="form-control" style="width: 50px; display: inline;">
@@ -89,8 +90,8 @@
             </div>
         </div>
         <div class="form-group">
-            <label class="col-xs-1 control-label">Range</label>
-            <div class="col-xs-4 controls">
+            <label class="col-xs-2 control-label">Range</label>
+            <div class="col-xs-5 controls">
                 <input name="p_range_lower" value="" type="hidden">
                 <input name="p_range_upper" value="" type="hidden">
                 <span style="display: inline;">
@@ -103,48 +104,45 @@
         </div>
         
         <div class="form-group">
-            <label for="corr_sample_method" class="col-xs-1 control-label"></label>
-            <div class="col-xs-4 controls">
+            <label for="corr_sample_method" class="col-xs-2 control-label"></label>
+            <div class="col-xs-3 controls">
                 <button class="btn corr_compute submit_special btn-success" data-url="/corr_compute" title="Compute Correlation">
                     <i class="icon-ok-circle icon-white"></i> Compute
                 </button>
             </div>
         </div>
-
-        <div class="form-group">
-            <label for="descriptions" class="col-xs-1 control-label"></label>
-            <div class="col-xs-6 controls">
-            <span id="sample_r_desc" class="correlation_desc fs12">
-                The <a href="http://genenetwork.org/correlationAnnotation.html#genetic_r">Sample Correlation</a>
-                is computed
-                between trait data and any
-                other traits in the sample database selected above. Use
-                <a href="http://www.genenetwork.org/glossary.html#Correlations">Spearman
-                Rank</a>
-                when the sample size is small (&lt;20) or when there are influential outliers.
-            </span>
-            <span id="lit_r_desc" style="display: none;" class="correlation_desc fs12">
-                The <a href="http://genenetwork.org/correlationAnnotation.html#literatureCorr">Literature Correlation</a>
-                (Lit r) between
-                this gene and all other genes is computed<br>
-                using the <a href="https://grits.eecs.utk.edu/sgo/sgo.html">
-                Semantic Gene Organizer</a>
-                and human, rat, and mouse data from PubMed.
-                Values are ranked by Lit r, but Sample r and Tissue r are also displayed.<br>
-                <a href="http://genenetwork.org/glossary.html#Literature">More on using Lit r</a>
-            </span>
-            <span id="tissue_r_desc" style="display: none;" class="correlation_desc fs12">
-                The <a href="http://genenetwork.org/webqtl/main.py?FormID=tissueCorrelation">Tissue Correlation</a>
-                (Tissue r)
-                estimates the similarity of expression of two genes
-                or transcripts across different cells, tissues, or organs
-                (<a href="http://genenetwork.org/correlationAnnotation.html#tissueCorr">glossary</a>).
-                Tissue correlations
-                are generated by analyzing expression in multiple samples usually taken from single cases.<br>
-                <strong>Pearson</strong> and <strong>Spearman Rank</strong> correlations have been
-                computed for all pairs of genes using data from mouse samples.<br>
-            </span>
-            </div>
-        </div>
     </div>
+  </div>
+  <div class="col-xs-5">
+    <span id="sample_r_desc" class="correlation_desc fs12">
+        The <a href="http://genenetwork.org/correlationAnnotation.html#genetic_r">Sample Correlation</a>
+        is computed
+        between trait data and any
+        other traits in the sample database selected above. Use
+        <a href="http://www.genenetwork.org/glossary.html#Correlations">Spearman
+        Rank</a>
+        when the sample size is small (&lt;20) or when there are influential outliers.
+    </span>
+    <span id="lit_r_desc" style="display: none;" class="correlation_desc fs12">
+        The <a href="http://genenetwork.org/correlationAnnotation.html#literatureCorr">Literature Correlation</a>
+        (Lit r) between
+        this gene and all other genes is computed<br>
+        using the <a href="https://grits.eecs.utk.edu/sgo/sgo.html">
+        Semantic Gene Organizer</a>
+        and human, rat, and mouse data from PubMed.
+        Values are ranked by Lit r, but Sample r and Tissue r are also displayed.<br>
+        <a href="http://genenetwork.org/glossary.html#Literature">More on using Lit r</a>
+    </span>
+    <span id="tissue_r_desc" style="display: none;" class="correlation_desc fs12">
+        The <a href="http://genenetwork.org/webqtl/main.py?FormID=tissueCorrelation">Tissue Correlation</a>
+        (Tissue r)
+        estimates the similarity of expression of two genes
+        or transcripts across different cells, tissues, or organs
+        (<a href="http://genenetwork.org/correlationAnnotation.html#tissueCorr">glossary</a>).
+        Tissue correlations
+        are generated by analyzing expression in multiple samples usually taken from single cases.<br>
+        <strong>Pearson</strong> and <strong>Spearman Rank</strong> correlations have been
+        computed for all pairs of genes using data from mouse samples.<br>
+    </span>
+  </div>
 </div>
\ No newline at end of file
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index dcec2b9e..03590c2c 100644
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -1,6 +1,6 @@
 <div>
-    {% if (use_pylmm_rqtl and dataset.group.species != "human") or use_plink_gemma %}
-    <div class="col-xs-4">
+    {% if dataset.group.mapping_names|length > 0 %}
+    <div class="col-xs-5">
         <div class="tabbable"> <!-- Only required for left/right tabs -->
 
             <ul class="nav nav-pills">
@@ -38,11 +38,11 @@
                 {# if use_pylmm_rqtl and not use_plink_gemma and dataset.group.species != "human" #}
                 {% if dataset.group.mapping_id == "1" %}
                 <div class="tab-pane active" id="gemma">
-                    <div style="padding-top: 10px;" class="form-horizontal">
+                    <div style="padding-top: 20px;" class="form-horizontal">
                         {% if genofiles and genofiles|length>0 %}
                         <div class="mapping_method_fields form-group">
-                            <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
-                            <div style="margin-left: 20px;" class="col-xs-8 controls">
+                            <label for="genofiles" style="text-align: right;" class="col-xs-3 control-label">Genotypes</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <select id="genofile_gemma" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
@@ -52,50 +52,72 @@
                         </div>
                         {% endif %}
                         <div class="mapping_method_fields form-group">
-                            <label for="maf_gemma" class="col-xs-5 control-label">Minor allele threshold</label>
-                            <div style="margin-left: 20px;" class="col-xs-3 controls">
+                            <label for="maf_gemma" style="text-align: right;" class="col-xs-3 control-label">MAF</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <input name="maf_gemma" value="0.01" type="text" class="form-control">
                             </div>
                         </div>
                         <div class="mapping_method_fields form-group">
-                            <label class="col-xs-4 control-label">Use LOCO</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align: right;" class="col-xs-3 control-label">Use LOCO</label>
+                            <div style="margin-left:20px;" class="col-xs-6 controls">
                                 <label class="radio-inline">
-                                    <input type="radio" name="use_loco" value="True">
+                                    <input type="radio" name="use_loco" value="True" checked="">
                                     Yes
                                 </label>
                                 <label class="radio-inline">
-                                    <input type="radio" name="use_loco" value="False" checked="">
+                                    <input type="radio" name="use_loco" value="False">
                                     No
                                </label>
                             </div>
                         </div>
+                    <!--
                     </div>
                     <div style="padding-top: 5px; padding-bottom: 5px; padding-left: 20px;" class="form-horizontal">
+                    -->
                         <div class="mapping_method_fields form-group">
-                            <button type="button" id="select_covariates" class="btn btn-default">
-                                Select Covariates
-                            </button>
-                            <button type="button" id="remove_covariates" class="btn btn-default">
-                                Remove Covariates
+                            <label style="text-align: right;" class="col-xs-3 control-label">Covariates</label>
+                            <div style="margin-left:20px;" class="col-xs-7">
+                              {% if g.user_session.user_ob and (g.user_session.user_ob.display_num_collections() == "") %}
+                              No collections available. Please add traits to a collection to use them as covariates.
+                              {% elif g.cookie_session.display_num_collections() == "" %}
+                              No collections available. Please add traits to a collection to use them as covariates.
+                              {% else %}
+                              <div style="margin-bottom: 10px;" class="btn-group" role="group">
+                                <button type="button" id="select_covariates" class="btn btn-default">Select</button>
+                                <button type="button" id="remove_covariates" class="btn btn-default">Remove</button>
+                              </div>
+                              <textarea rows="3" cols="20" readonly placeholder="No covariates selected" style="overflow-y: scroll; resize: none;" class="selected_covariates"></textarea>
+                              {% endif %}
+                            </div>
+                        </div>
+                        <div class="mapping_method_fields form-group">
+                          <label class="col-xs-3 control-label"></label>
+                          <div style="margin-left:20px;" class="col-xs-6">
+                            <button id="gemma_bimbam_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
+                                Compute
                             </button>
+                          </div>
                         </div>
                     </div>
-
+<!--
                     <div class="form-group">
                         <div class="col-xs-4 controls">
+                            <label class="col-xs-2 control-label"></label>
+                            <div class="col-xs-4">
                             <button id="gemma_bimbam_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
                                 Compute
                             </button>
+                            </div>
                         </div>
                     </div>
+-->
                 </div>
                 <div class="tab-pane" id="interval_mapping">
                     <div style="margin-top: 20px" class="form-horizontal">
                         {% if genofiles and genofiles|length>0 %}
                         <div class="mapping_method_fields form-group">
-                            <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
-                            <div style="margin-left: 20px;" class="col-xs-8 controls">
+                            <label style="text-align: right;" for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <select id="genofile_reaper" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
@@ -105,20 +127,20 @@
                         </div>
                         {% endif %}
                         <div class="mapping_method_fields form-group">
-                            <label for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align: right;" for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <input name="num_perm_reaper" value="2000" type="text" class="form-control">
                             </div>
                         </div>
                         <div class="mapping_method_fields form-group">
-                            <label for="mapping_bootstraps" class="col-xs-3 control-label">Bootstraps</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align: right;" for="mapping_bootstraps" class="col-xs-3 control-label">Bootstraps</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <input name="num_bootstrap" value="2000" type="text" class="form-control">
                             </div>
                         </div>
                         <div class="mapping_method_fields form-group">
-                            <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align: right;" for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
+                            <div style="margin-left:20px;" class="col-xs-6 controls">
                                 {% if dataset.type == 'ProbeSet' and this_trait.locus_chr != "" %}
                                 <input name="control_reaper" value="{{ nearest_marker }}" type="text" style="width: 160px;" class="form-control" />
                                 {% else %}
@@ -162,8 +184,8 @@
 
 
                         <div class="mapping_method_fields form-group">
-                            <label style="text-align:left;" class="col-xs-3 control-label">Marker<br>Regression</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align: right;" class="col-xs-3 control-label">Marker<br>Regression</label>
+                            <div style="margin-left:20px;" class="col-xs-6 controls">
                                 <label class="radio-inline">
                                     <input type="radio" name="manhattan_plot_reaper" value="True">
                                     Yes
@@ -174,11 +196,12 @@
                                </label>
                             </div>
                         </div>
-                        <div class="form-group">
-                            <div style="padding-left:15px;" class="controls">
-                                <button id="interval_mapping_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping">
-                                    <i class="icon-ok-circle icon-white"></i> Compute
-                                </button>
+                        <div class="mapping_method_fields form-group">
+                            <label class="col-xs-3 control-label"></label>
+                            <div style="margin-left:20px;" class="col-xs-6">
+                              <button id="interval_mapping_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping">
+                                  Compute
+                              </button>
                             </div>
                         </div>
                         <!--<div id="alert_placeholder"></div>-->
@@ -189,8 +212,8 @@
                     <div style="margin-top: 20px" class="form-horizontal">
                         {% if genofiles and genofiles|length>0 %}
                         <div class="mapping_method_fields form-group">
-                            <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
-                            <div style="margin-left: 20px;" class="col-xs-8 controls">
+                            <label style="text-align:right;" for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                                 <select id="genofile_rqtl_geno" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
@@ -200,17 +223,14 @@
                         </div>
                         {% endif %}
                         <div class="mapping_method_fields form-group">
-                            <label for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
-                                <input name="num_perm_rqtl_geno" value="" type="text" class="form-control">
+                            <label style="text-align:right;" for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
+                                <input name="num_perm_rqtl_geno" value="2000" type="text" class="form-control">
                             </div>
                         </div>
-                        <div id="permutations_alert" class="alert alert-error alert-warning" style="display:none;">
-                            Please be aware that permutations can take a very long time (~20 minutes for 500 permutations)
-                        </div>
                         <div class="mapping_method_fields form-group">
-                            <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <label style="text-align:right;" for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
+                            <div style="margin-left:20px;" class="col-xs-6 controls">
                                 {% if dataset.type == 'ProbeSet' and this_trait.locus_chr != "" %}
                                 <input name="control_rqtl_geno" value="{{ nearest_marker }}" type="text" style="width: 160px;" class="form-control" />
                                 {% else %}
@@ -228,8 +248,8 @@
                         </div>
 
                         <div class="mapping_method_fields form-group">
-                            <label for="mapmethod_rqtl_geno" style="text-align:left;" class="col-xs-3 control-label">Method</label>
-                            <div class="col-xs-4 controls">
+                            <label style="text-align:right;" for="mapmethod_rqtl_geno" class="col-xs-3 control-label">Method</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                               <select name="mapmethod_rqtl_geno" class="form-control">
                                 <option value="em">em</option>
                                 <option value="imp">imp</option>
@@ -243,8 +263,8 @@
                         </div>
 
                         <div class="mapping_method_fields form-group">
-                            <label for="mapmodel_rqtl_geno" style="text-align:left;" class="col-xs-3 control-label">Model</label>
-                            <div class="col-xs-4 controls">
+                            <label style="text-align:right;" for="mapmodel_rqtl_geno" class="col-xs-3 control-label">Model</label>
+                            <div style="margin-left:20px;" class="col-xs-4 controls">
                               <select name="mapmodel_rqtl_geno" class="form-control">
                                 <option value="normal">normal</option>
                                 <!--<option value="binary">binary</option>
@@ -269,8 +289,8 @@
                         </div>
                         -->
                         <div class="mapping_method_fields form-group">
-                            <label style="text-align:left;" class="col-xs-12 control-label">Manhattan Plot</label>
-                            <div class="col-xs-12 controls">
+                            <label style="text-align:right;" class="col-xs-3 control-label">Marker<br>Regression</label>
+                            <div style="margin-left:20px;" class="col-xs-6 controls">
                                 <label class="radio-inline">
                                     <input type="radio" name="manhattan_plot_rqtl" value="True">
                                     Yes
@@ -282,11 +302,12 @@
                             </div>
                         </div>
 
-                        <div class="form-group">
-                            <div style="padding-left:15px;" class="controls">
-                                <button id="rqtl_geno_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
-                                    <i class="icon-ok-circle icon-white"></i> Compute
-                                </button>
+                        <div class="mapping_method_fields form-group">
+                            <label class="col-xs-3 control-label"></label>
+                            <div style="margin-left:20px;" class="col-xs-6">
+                              <button id="rqtl_geno_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping">
+                                  Compute
+                              </button>
                             </div>
                         </div>
                     </div>
@@ -295,8 +316,8 @@
                     <div style="margin-top: 20px" class="form-horizontal">
                         {% if genofiles and genofiles|length>0 %}
                         <div class="mapping_method_fields form-group">
-                            <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
-                            <div style="margin-left: 20px;" class="col-xs-8 controls">
+                            <label style="text-align:right;" class="col-xs-3 control-label">Genotypes</label>
+                            <div style="margin-left: 20px;" class="col-xs-4 controls">
                                 <select id="genofile_pylmm" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
@@ -305,44 +326,12 @@
                             </div>
                         </div>
                         {% endif %}
-<!--
                         <div class="mapping_method_fields form-group">
-                            <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
-                                {% if dataset.type == 'ProbeSet' and this_trait.locus_chr != "" %}
-                                <input name="control_pylmm" value="{{ nearest_marker }}" type="text" />
-                                {% else %}
-                                <input name="control_pylmm" value="" type="text" />
-                                {% endif %}
-                                <label class="radio-inline">
-                                    <input type="radio" name="do_control_pylmm" value="true">
-                                    Yes
-                                </label>
-                                <label class="radio-inline">
-                                    <input type="radio" name="do_control_pylmm" value="false" checked="">
-                                    No
-                                </label>
-                            </div>
-                        </div>
-                        <div class="mapping_method_fields form-group">
-                            <label style="text-align:left;" class="col-xs-12 control-label">Manhattan Plot</label>
-                            <div class="col-xs-12 controls">
-                                <label class="radio-inline">
-                                    <input type="radio" name="manhattan_plot_pylmm" value="True">
-                                    Yes
-                                </label>
-                                <label class="radio-inline">
-                                    <input type="radio" name="manhattan_plot_pylmm" value="False" checked="">
-                                    No
-                               </label>
-                            </div>
-                        </div>
--->
-                        <div class="form-group">
-                            <div style="padding-left:15px;" class="controls">
-                                <button id="pylmm_compute" class="btn submit_special btn-success" title="Compute Marker Regression">
-                                    <i class="icon-ok-circle icon-white"></i> Compute
-                                </button>
+                            <label class="col-xs-3 control-label"></label>
+                            <div style="margin-left:20px;" class="col-xs-6">
+                              <button id="pylmm_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping">
+                                  Compute
+                              </button>
                             </div>
                         </div>
                     </div>
@@ -354,8 +343,8 @@
                     <div style="padding-top: 10px;" class="form-horizontal">
                         {% if genofiles and genofiles|length>0 %}
                         <div class="mapping_method_fields form-group">
-                            <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
-                            <div style="margin-left: 20px;" class="col-xs-8 controls">
+                            <label style="text-align:right;" class="col-xs-3 control-label">Genotypes</label>
+                            <div style="margin-left: 20px;" class="col-xs-4 controls">
                                 <select id="genofile_gemma" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
@@ -365,29 +354,34 @@
                         </div>
                         {% endif %}
                         <div class="mapping_method_fields form-group">
-                            <label for="maf_gemma" class="col-xs-5 control-label">Minor allele threshold</label>
-                            <div style="margin-left: 20px;" class="col-xs-3 controls">
+                            <label style="text-align:right;" class="col-xs-3 control-label">MAF</label>
+                            <div style="margin-left: 20px;" class="col-xs-4 controls">
                                 <input name="maf_gemma" value="0.01" type="text" class="form-control">
                             </div>
                         </div>
-                    </div>
-
-                    <div style="padding-top: 5px; padding-bottom: 5px; padding-left: 20px;" class="form-horizontal">
                         <div class="mapping_method_fields form-group">
-                            <button type="button" id="select_covariates" class="btn btn-default">
-                                Select Covariates
-                            </button>
-                            <button type="button" id="remove_covariates" class="btn btn-default">
-                                Remove Covariates
-                            </button>
+                            <label style="text-align: right;" class="col-xs-3 control-label">Covariates</label>
+                            <div style="margin-left:20px;" class="col-xs-7">
+                              {% if g.user_session.user_ob and (g.user_session.user_ob.display_num_collections() == "") %}
+                              No collections available. Please add traits to a collection to use them as covariates.
+                              {% elif g.cookie_session.display_num_collections() == "" %}
+                              No collections available. Please add traits to a collection to use them as covariates.
+                              {% else %}
+                              <div style="margin-bottom: 10px;" class="btn-group" role="group">
+                                <button type="button" id="select_covariates" class="btn btn-default">Select</button>
+                                <button type="button" id="remove_covariates" class="btn btn-default">Remove</button>
+                              </div>
+                              <textarea rows="3" cols="20" readonly placeholder="No covariates selected" style="overflow-y: scroll; resize: none;" class="selected_covariates"></textarea>
+                              {% endif %}
+                            </div>
                         </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="col-xs-4 controls">
+                        <div class="mapping_method_fields form-group">
+                          <label class="col-xs-3 control-label"></label>
+                          <div style="margin-left:20px;" class="col-xs-6">
                             <button id="gemma_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
                                 Compute
                             </button>
+                          </div>
                         </div>
                     </div>
                 </div>
@@ -395,16 +389,16 @@
                 <div class="tab-pane" id="plink">
                     <div style="padding: 20px" class="form-horizontal">
                         <div class="mapping_method_fields form-group">
-                            <label for="maf_plink" class="col-xs-3 control-label">Minor allele threshold</label>
-                            <div style="margin-left: 20px;" class="col-xs-3 controls">
+                            <label style="text-align: right;" class="col-xs-3 control-label">MAF</label>
+                            <div style="margin-left: 20px;" class="col-xs-4 controls">
                                 <input name="maf_plink" value="0.01" type="text" class="form-control">
                             </div>
                         </div>
                     </div>
 
                     <div class="form-group">
-                        <label for="plink_compute" class="col-xs-1 control-label"></label>
-                        <div style="margin-left:20px;" class="col-xs-4 controls">
+                        <label style="text-align: right;" class="col-xs-3 control-label"></label>
+                        <div style="margin-left:20px;" class="col-xs-6 controls">
                             <button id="plink_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
                                 Compute
                             </button>
@@ -416,25 +410,29 @@
             </div>
         </div>
     </div>
-    <div class="col-xs-6">
+    <div class="col-xs-5">
         {% if dataset.group.mapping_id == "1" %}
         <dl>
+             <dt>GEMMA</dt>
+             <dd>GEMMA is software implementing the Genome-wide Efficient Mixed Model Association algorithm for a standard linear mixed model for genome-wide association studies (GWAS).</dd>
              <dt>Interval Mapping</dt>
              <dd>Interval mapping is a process in which the statistical significance of a hypothetical QTL is evaluated at regular points across a chromosome, even in the absence of explicit genotype data at those points.</dd>
-             <dt>pyLMM</dt>
-             <dd>pyLMM is a fast and lightweight linear mixed-model (LMM) solver for use in genome-wide association studies (GWAS).</dd>
              <dt>R/qtl</dt>
              <dd>R/qtl is an extensible, interactive environment for mapping quantitative trait loci (QTL) in experimental crosses.</dd>
+             <dt>pyLMM</dt>
+             <dd>pyLMM is a fast and lightweight linear mixed-model (LMM) solver for use in genome-wide association studies (GWAS).</dd>
         </dl>
         {% else %}
         <dl>
+            {% if mapping_method == "GEMMA" %}
             <dt>GEMMA</dt>
             <dd>
                 GEMMA is software implementing the Genome-wide Efficient Mixed Model Association algorithm for a standard linear mixed model for genome-wide association studies (GWAS).<br>
-                Note: There currently exists an issue where GEMMA can't be run on traits from the same group simultaneously. If you receive an error, please wait a few minutes and try again.
             </dd>
+            {% elif mapping_method == "PLINK" %}
             <dt>PLINK</dt>
             <dd>PLINK is a free, open-source whole genome association analysis toolset.</dd>
+            {% endif %}
         </dl>
         {% endif %}
     </div>
diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py
index c344ea27..ebca4807 100644
--- a/wqflask/wqflask/user_manager.py
+++ b/wqflask/wqflask/user_manager.py
@@ -55,7 +55,10 @@ logger = getLogger(__name__)
 from base.data_set import create_datasets_list
 
 import requests
-from utility.elasticsearch_tools import get_elasticsearch_connection, get_user_by_unique_column, save_user
+from utility.elasticsearch_tools import get_elasticsearch_connection, get_user_by_unique_column, get_item_by_unique_column, save_user, es_save_data
+
+from smtplib import SMTP
+from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD
 
 THREE_DAYS = 60 * 60 * 24 * 3
 #THREE_DAYS = 45
@@ -386,6 +389,7 @@ class ForgotPasswordEmail(VerificationEmail):
             "email_address": toaddr,
             "timestamp": timestamp()
         }
+        es = get_elasticsearch_connection()
         es_save_data(es, self.key_prefix, "local", data, verification_code)
 
         subject = self.subject
@@ -437,12 +441,12 @@ def verify_email():
 @app.route("/n/password_reset", methods=['GET'])
 def password_reset():
     logger.debug("in password_reset request.url is:", request.url)
-
     # We do this mainly just to assert that it's in proper form for displaying next page
     # Really not necessary but doesn't hurt
     # user_encode = DecodeUser(ForgotPasswordEmail.key_prefix).reencode_standalone()
     verification_code = request.args.get('code')
     hmac = request.args.get('hm')
+    es = get_elasticsearch_connection()
     if verification_code:
         code_details = get_item_by_unique_column(
             es
@@ -466,7 +470,6 @@ def password_reset():
 
 @app.route("/n/password_reset_step2", methods=('POST',))
 def password_reset_step2():
-    from utility.elasticsearch_tools import es
     logger.debug("in password_reset request.url is:", request.url)
 
     errors = []
@@ -626,13 +629,12 @@ class LoginUser(object):
         logger.debug("in login params are:", params)
         es = get_elasticsearch_connection()
         if not params:
-            from utility.tools import GITHUB_AUTH_URL, ORCID_AUTH_URL
-            external_login = None
-            if GITHUB_AUTH_URL or ORCID_AUTH_URL:
-                external_login={
-                    "github": GITHUB_AUTH_URL,
-                    "orcid": ORCID_AUTH_URL
-                }
+            from utility.tools import GITHUB_AUTH_URL, GITHUB_CLIENT_ID, ORCID_AUTH_URL, ORCID_CLIENT_ID
+            external_login = {}
+            if GITHUB_AUTH_URL and GITHUB_CLIENT_ID != 'UNKNOWN':
+                external_login["github"] = GITHUB_AUTH_URL
+            if ORCID_AUTH_URL and ORCID_CLIENT_ID != 'UNKNOWN':
+                external_login["orcid"] = ORCID_AUTH_URL
             assert(es is not None)
             return render_template(
                 "new_security/login_user.html"
@@ -749,6 +751,7 @@ def forgot_password():
 def forgot_password_submit():
     params = request.form
     email_address = params['email_address']
+    es = get_elasticsearch_connection()
     user_details = get_user_by_unique_column(es, "email_address", email_address)
     if user_details:
         ForgotPasswordEmail(user_details["email_address"])
@@ -915,15 +918,26 @@ app.jinja_env.globals.update(url_for_hmac=url_for_hmac,
 #     Redis.rpush("mail_queue", msg)
 
 def send_email(toaddr, msg, fromaddr="no-reply@genenetwork.org"):
-    from smtplib import SMTP
-    from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD
-    server = SMTP(SMTP_CONNECT)
-    server.starttls()
-    server.login(SMTP_USERNAME, SMTP_PASSWORD)
-    server.sendmail(fromaddr, toaddr, msg)
-    server.quit()
-
-
+    """Send an E-mail through SMTP_CONNECT host. If SMTP_USERNAME is not
+    'UNKNOWN' TLS is used
+
+    """
+    if SMTP_USERNAME == 'UNKNOWN':
+        logger.debug("SMTP: connecting with host "+SMTP_CONNECT)
+        server = SMTP(SMTP_CONNECT)
+        server.sendmail(fromaddr, toaddr, msg)
+    else:
+        logger.debug("SMTP: connecting TLS with host "+SMTP_CONNECT)
+        server = SMTP(SMTP_CONNECT)
+        server.starttls()
+        logger.debug("SMTP: login with user "+SMTP_USERNAME)
+        server.login(SMTP_USERNAME, SMTP_PASSWORD)
+        logger.debug("SMTP: "+fromaddr)
+        logger.debug("SMTP: "+toaddr)
+        logger.debug("SMTP: "+msg)
+        server.sendmail(fromaddr, toaddr, msg)
+        server.quit()
+    logger.info("Successfully sent email to "+toaddr)
 
 class GroupsManager(object):
     def __init__(self, kw):
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index 4e81c29c..a65924d8 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -123,7 +123,7 @@ def handle_bad_request(e):
 @app.route("/")
 def index_page():
     logger.info("Sending index_page")
-    logger.error(request.url)
+    logger.info(request.url)
     params = request.args
     if 'import_collections' in params:
         import_collections = params['import_collections']
@@ -141,7 +141,7 @@ def index_page():
 def tmp_page(img_path):
     logger.info("In tmp_page")
     logger.info("img_path:", img_path)
-    logger.error(request.url)
+    logger.info(request.url)
     initial_start_vars = request.form
     logger.info("initial_start_vars:", initial_start_vars)
     imgfile = open(GENERATED_IMAGE_DIR + img_path, 'rb')
@@ -174,7 +174,7 @@ def twitter(filename):
 @app.route("/search", methods=('GET',))
 def search_page():
     logger.info("in search_page")
-    logger.error(request.url)
+    logger.info(request.url)
     if 'info_database' in request.args:
         logger.info("Going to sharing_info_page")
         template_vars = sharing_info_page()
@@ -199,21 +199,22 @@ def search_page():
         logger.info("request.args is", request.args)
         the_search = search_results.SearchResultPage(request.args)
         result = the_search.__dict__
+        valid_search = result['search_term_exists']
 
         logger.debugf("result", result)
 
-        if USE_REDIS:
+        if USE_REDIS and valid_search:
             Redis.set(key, pickle.dumps(result, pickle.HIGHEST_PROTOCOL))
             Redis.expire(key, 60*60)
 
-        if result['search_term_exists']:
+        if valid_search:
             return render_template("search_result_page.html", **result)
         else:
             return render_template("search_error.html")
 
 @app.route("/gsearch", methods=('GET',))
 def gsearchact():
-    logger.error(request.url)
+    logger.info(request.url)
     result = gsearch.GSearch(request.args).__dict__
     type = request.args['type']
     if type == "gene":
@@ -224,7 +225,7 @@ def gsearchact():
 @app.route("/gsearch_updating", methods=('POST',))
 def gsearch_updating():
     logger.info("REQUEST ARGS:", request.values)
-    logger.error(request.url)
+    logger.info(request.url)
     result = update_search_results.GSearch(request.args).__dict__
     return result['results']
     # type = request.args['type']
@@ -235,31 +236,31 @@ def gsearch_updating():
 
 @app.route("/docedit")
 def docedit():
-    logger.error(request.url)
+    logger.info(request.url)
     doc = docs.Docs(request.args['entry'])
     return render_template("docedit.html", **doc.__dict__)
 
 @app.route('/generated/<filename>')
 def generated_file(filename):
-    logger.error(request.url)
+    logger.info(request.url)
     return send_from_directory(GENERATED_IMAGE_DIR,filename)
 
 @app.route("/help")
 def help():
-    logger.error(request.url)
+    logger.info(request.url)
     doc = docs.Docs("help")
     return render_template("docs.html", **doc.__dict__)
 
 @app.route("/wgcna_setup", methods=('POST',))
 def wcgna_setup():
     logger.info("In wgcna, request.form is:", request.form)             # We are going to get additional user input for the analysis
-    logger.error(request.url)
+    logger.info(request.url)
     return render_template("wgcna_setup.html", **request.form)          # Display them using the template
 
 @app.route("/wgcna_results", methods=('POST',))
 def wcgna_results():
     logger.info("In wgcna, request.form is:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     wgcna = wgcna_analysis.WGCNA()                                # Start R, load the package and pointers and create the analysis
     wgcnaA = wgcna.run_analysis(request.form)                     # Start the analysis, a wgcnaA object should be a separate long running thread
     result = wgcna.process_results(wgcnaA)                        # After the analysis is finished store the result
@@ -268,13 +269,13 @@ def wcgna_results():
 @app.route("/ctl_setup", methods=('POST',))
 def ctl_setup():
     logger.info("In ctl, request.form is:", request.form)             # We are going to get additional user input for the analysis
-    logger.error(request.url)
+    logger.info(request.url)
     return render_template("ctl_setup.html", **request.form)          # Display them using the template
 
 @app.route("/ctl_results", methods=('POST',))
 def ctl_results():
     logger.info("In ctl, request.form is:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     ctl = ctl_analysis.CTL()                                  # Start R, load the package and pointers and create the analysis
     ctlA = ctl.run_analysis(request.form)                     # Start the analysis, a ctlA object should be a separate long running thread
     result = ctl.process_results(ctlA)                        # After the analysis is finished store the result
@@ -313,13 +314,13 @@ def environments():
 
 @app.route("/submit_trait")
 def submit_trait_form():
-    logger.error(request.url)
+    logger.info(request.url)
     species_and_groups = get_species_groups()
     return render_template("submit_trait.html", **{'species_and_groups' : species_and_groups, 'gn_server_url' : GN_SERVER_URL, 'version' : GN_VERSION})
 
 @app.route("/create_temp_trait", methods=('POST',))
 def create_temp_trait():
-    logger.error(request.url)
+    logger.info(request.url)
     print("REQUEST.FORM:", request.form)
     #template_vars = submit_trait.SubmitTrait(request.form)
 
@@ -332,7 +333,7 @@ def export_trait_excel():
     """Excel file consisting of the sample data from the trait data and analysis page"""
     logger.info("In export_trait_excel")
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     sample_data = export_trait_data.export_sample_table(request.form)
 
     logger.info("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data)))
@@ -358,7 +359,7 @@ def export_trait_csv():
     """CSV file consisting of the sample data from the trait data and analysis page"""
     logger.info("In export_trait_csv")
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     sample_data = export_trait_data.export_sample_table(request.form)
 
     logger.info("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data)))
@@ -379,7 +380,7 @@ def export_traits_csv():
     """CSV file consisting of the traits from the search result page"""
     logger.info("In export_traits_csv")
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     csv_data = export_traits.export_search_results_csv(request.form)
 
     return Response(csv_data,
@@ -389,7 +390,7 @@ def export_traits_csv():
 @app.route('/export_perm_data', methods=('POST',))
 def export_perm_data():
     """CSV file consisting of the permutation data for the mapping results"""
-    logger.error(request.url)
+    logger.info(request.url)
     num_perm = float(request.form['num_perm'])
     perm_data = json.loads(request.form['perm_results'])
 
@@ -412,7 +413,7 @@ def export_perm_data():
 
 @app.route("/show_temp_trait", methods=('POST',))
 def show_temp_trait_page():
-    logger.error(request.url)
+    logger.info(request.url)
     template_vars = show_trait.ShowTrait(request.form)
     #logger.info("js_data before dump:", template_vars.js_data)
     template_vars.js_data = json.dumps(template_vars.js_data,
@@ -427,7 +428,7 @@ def show_temp_trait_page():
 
 @app.route("/show_trait")
 def show_trait_page():
-    logger.error(request.url)
+    logger.info(request.url)
     template_vars = show_trait.ShowTrait(request.args)
     #logger.info("js_data before dump:", template_vars.js_data)
     template_vars.js_data = json.dumps(template_vars.js_data,
@@ -443,7 +444,7 @@ def show_trait_page():
 @app.route("/heatmap", methods=('POST',))
 def heatmap_page():
     logger.info("In heatmap, request.form is:", pf(request.form))
-    logger.error(request.url)
+    logger.info(request.url)
 
     start_vars = request.form
     temp_uuid = uuid.uuid4()
@@ -493,7 +494,7 @@ def mapping_results_container_page():
 
 @app.route("/loading", methods=('POST',))
 def loading_page():
-    logger.error(request.url)
+    logger.info(request.url)
     initial_start_vars = request.form
     logger.debug("Marker regression called with initial_start_vars:", initial_start_vars.items())
     #temp_uuid = initial_start_vars['temp_uuid']
@@ -552,7 +553,7 @@ def loading_page():
 def marker_regression_page():
     initial_start_vars = request.form
     logger.debug("Marker regression called with initial_start_vars:", initial_start_vars.items())
-    logger.error(request.url)
+    logger.info(request.url)
     temp_uuid = initial_start_vars['temp_uuid']
     wanted = (
         'trait_id',
@@ -582,7 +583,7 @@ def marker_regression_page():
         'control_marker',
         'control_marker_db',
         'do_control',
-        'genofile',
+        'genofile_string',
         'pair_scan',
         'startMb',
         'endMb',
@@ -678,7 +679,7 @@ def marker_regression_page():
 @app.route("/export_mapping_results", methods = ('POST',))
 def export_mapping_results():
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     file_path = request.form.get("results_path")
     results_csv = open(file_path, "r").read()
     response = Response(results_csv,
@@ -691,7 +692,7 @@ def export_mapping_results():
 @app.route("/export", methods = ('POST',))
 def export():
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     svg_xml = request.form.get("data", "Invalid data")
     filename = request.form.get("filename", "manhattan_plot_snp")
     response = Response(svg_xml, mimetype="image/svg+xml")
@@ -702,7 +703,7 @@ def export():
 def export_pdf():
     import cairosvg
     logger.info("request.form:", request.form)
-    logger.error(request.url)
+    logger.info(request.url)
     svg_xml = request.form.get("data", "Invalid data")
     logger.info("svg_xml:", svg_xml)
     filename = request.form.get("filename", "interval_map_pdf")
@@ -715,7 +716,7 @@ def export_pdf():
 @app.route("/network_graph", methods=('POST',))
 def network_graph_page():
     logger.info("In network_graph, request.form is:", pf(request.form))
-    logger.error(request.url)
+    logger.info(request.url)
     start_vars = request.form
     traits = [trait.strip() for trait in start_vars['trait_list'].split(',')]
     if traits[0] != "":
@@ -731,7 +732,7 @@ def network_graph_page():
 @app.route("/corr_compute", methods=('POST',))
 def corr_compute_page():
     logger.info("In corr_compute, request.form is:", pf(request.form))
-    logger.error(request.url)
+    logger.info(request.url)
     #fd = webqtlFormData.webqtlFormData(request.form)
     template_vars = show_corr_results.CorrelationResults(request.form)
     return render_template("correlation_page.html", **template_vars.__dict__)
@@ -739,11 +740,11 @@ def corr_compute_page():
 @app.route("/corr_matrix", methods=('POST',))
 def corr_matrix_page():
     logger.info("In corr_matrix, request.form is:", pf(request.form))
-    logger.error(request.url)
+    logger.info(request.url)
 
     start_vars = request.form
     traits = [trait.strip() for trait in start_vars['trait_list'].split(',')]
-    if traits[0] != "":
+    if len(traits) > 1:
         template_vars = show_corr_matrix.CorrelationMatrix(start_vars)
         template_vars.js_data = json.dumps(template_vars.js_data,
                                            default=json_default_handler,
@@ -755,7 +756,7 @@ def corr_matrix_page():
 
 @app.route("/corr_scatter_plot")
 def corr_scatter_plot_page():
-    logger.error(request.url)
+    logger.info(request.url)
     template_vars = corr_scatter_plot.CorrScatterPlot(request.args)
     template_vars.js_data = json.dumps(template_vars.js_data,
                                        default=json_default_handler,
@@ -764,7 +765,7 @@ def corr_scatter_plot_page():
 
 @app.route("/submit_bnw", methods=('POST',))
 def submit_bnw():
-    logger.error(request.url)
+    logger.info(request.url)
     template_vars = get_bnw_input(request.form)
     return render_template("empty_collection.html", **{'tool':'Correlation Matrix'})
 
@@ -772,7 +773,7 @@ def submit_bnw():
 def sharing_info_page():
     """Info page displayed when the user clicks the "Info" button next to the dataset selection"""
     logger.info("In sharing_info_page")
-    logger.error(request.url)
+    logger.info(request.url)
     fd = webqtlFormData.webqtlFormData(request.args)
     template_vars = SharingInfoPage.SharingInfoPage(fd)
     return template_vars
@@ -780,7 +781,7 @@ def sharing_info_page():
 # Take this out or secure it before putting into production
 @app.route("/get_temp_data")
 def get_temp_data():
-    logger.error(request.url)
+    logger.info(request.url)
     temp_uuid = request.args['key']
     return flask.jsonify(temp_data.TempData(temp_uuid).get_all())