about summary refs log tree commit diff
path: root/wqflask
diff options
context:
space:
mode:
Diffstat (limited to 'wqflask')
-rw-r--r--wqflask/__init__.py1
-rw-r--r--wqflask/base/data_set.py2
-rw-r--r--wqflask/base/webqtlConfig.py1
-rw-r--r--wqflask/run_gunicorn.py19
-rw-r--r--wqflask/runserver.py14
-rw-r--r--wqflask/utility/logger.py2
-rw-r--r--wqflask/utility/tools.py35
-rw-r--r--wqflask/wqflask/correlation/show_corr_results.py100
-rw-r--r--wqflask/wqflask/marker_regression/gemma_mapping.py16
-rw-r--r--wqflask/wqflask/marker_regression/marker_regression.py10
-rw-r--r--wqflask/wqflask/marker_regression/marker_regression_gn1.py17
-rw-r--r--wqflask/wqflask/static/new/javascript/dataset_menu_structure.json24
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js1
-rw-r--r--wqflask/wqflask/templates/loading.html18
-rw-r--r--wqflask/wqflask/templates/marker_regression_gn1.html22
-rw-r--r--wqflask/wqflask/templates/show_trait.html2
-rw-r--r--wqflask/wqflask/templates/show_trait_details.html31
-rw-r--r--wqflask/wqflask/templates/show_trait_mapping_tools.html174
-rw-r--r--wqflask/wqflask/views.py3
-rw-r--r--wqflask/wsgi.py4
20 files changed, 328 insertions, 168 deletions
diff --git a/wqflask/__init__.py b/wqflask/__init__.py
index 315b709e..e69de29b 100644
--- a/wqflask/__init__.py
+++ b/wqflask/__init__.py
@@ -1 +0,0 @@
-from wqflask import app
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 6649f8af..a4eaaa2e 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -332,7 +332,7 @@ class DatasetGroup(object):
         if check_plink_gemma():
             marker_class = HumanMarkers
         else:
-            marker_class = Markers            
+            marker_class = Markers
 
         if self.genofile:
             self.markers = marker_class(self.genofile[:-5])
diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py
index 1ef2bc26..1e66e957 100644
--- a/wqflask/base/webqtlConfig.py
+++ b/wqflask/base/webqtlConfig.py
@@ -82,6 +82,7 @@ assert_writable_dir(GENERATED_TEXT_DIR)
 # Flat file directories
 GENODIR              = flat_files('genotype')+'/'
 assert_dir(GENODIR)
+assert_dir(GENODIR+'bimbam') # for gemma
 
 # JSON genotypes are OBSOLETE
 JSON_GENODIR         = flat_files('genotype/json')+'/'
diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py
new file mode 100644
index 00000000..14a2d689
--- /dev/null
+++ b/wqflask/run_gunicorn.py
@@ -0,0 +1,19 @@
+# Run with gunicorn, see ./bin/genenetwork2 for an example
+#
+# Run standalone with
+#
+#   ./bin/genenetwork2 ./etc/default_settings.py -c run_gunicorn.py
+
+# from flask import Flask
+# application = Flask(__name__)
+
+print "Starting up Gunicorn process"
+
+from wqflask import app
+
+@app.route("/gunicorn")
+def hello():
+    return "<h1 style='color:blue'>Hello There!</h1>"
+
+if __name__ == "__main__":
+    app.run(host='0.0.0.0')
diff --git a/wqflask/runserver.py b/wqflask/runserver.py
index 50805643..a0c76e51 100644
--- a/wqflask/runserver.py
+++ b/wqflask/runserver.py
@@ -1,5 +1,7 @@
 # Starts the webserver with the ./bin/genenetwork2 command
 #
+# This uses Werkzeug WSGI, see ./run_gunicorn.py for the alternative
+#
 # Please note, running with host set externally below combined with
 # debug mode is a security risk unless you have a firewall setup, e.g.
 #
@@ -22,11 +24,19 @@ ENDC  = '\033[0m'
 import os
 app.config['SECRET_KEY'] = os.urandom(24)
 
-from utility.tools import WEBSERVER_MODE,get_setting_int
+from utility.tools import WEBSERVER_MODE,get_setting_int,get_setting,get_setting_bool
 
 port = get_setting_int("SERVER_PORT")
 
-logger.info("GN2 is running. Visit %shttp://localhost:%s/%s" % (BLUE,port,ENDC))
+print("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]")
+
+if get_setting_bool("USE_GN_SERVER"):
+    import requests
+    page = requests.get(get_setting("GN_SERVER_URL"))
+    if page.status_code != 200:
+        raise Exception("API server not found!")
+
+print("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL")))
 
 werkzeug_logger = logging.getLogger('werkzeug')
 
diff --git a/wqflask/utility/logger.py b/wqflask/utility/logger.py
index bacb0aa4..128706df 100644
--- a/wqflask/utility/logger.py
+++ b/wqflask/utility/logger.py
@@ -72,7 +72,7 @@ LOG_LEVEL_DEBUG (NYI).
     def warning(self,*args):
         """Call logging.warning for multiple args"""
         self.collect(self.logger.warning,*args)
-        self.logger.warning(self.collect(*args))
+        # self.logger.warning(self.collect(*args))
 
     def error(self,*args):
         """Call logging.error for multiple args"""
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index c5685cdd..d3113302 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -16,7 +16,7 @@ OVERRIDES = {}
 def app_set(command_id, value):
     """Set application wide value"""
     app.config.setdefault(command_id,value)
-    value
+    return value
 
 def get_setting(command_id,guess=None):
     """Resolve a setting from the environment or the global settings in
@@ -51,7 +51,7 @@ def get_setting(command_id,guess=None):
             return None
 
     # ---- Check whether environment exists
-    logger.debug("Looking for "+command_id+"\n")
+    # print("Looking for "+command_id+"\n")
     command = value(os.environ.get(command_id))
     if command is None or command == "":
         command = OVERRIDES.get(command_id)
@@ -63,7 +63,7 @@ def get_setting(command_id,guess=None):
                 if command is None or command == "":
                     # print command
                     raise Exception(command_id+' setting unknown or faulty (update default_settings.py?).')
-    logger.debug("Set "+command_id+"="+str(command))
+    # print("Set "+command_id+"="+str(command))
     return command
 
 def get_setting_bool(id):
@@ -105,7 +105,7 @@ def js_path(module=None):
     try_guix = get_setting("JS_GUIX_PATH")+"/"+module
     if valid_path(try_guix):
         return try_guix
-    raise "No JS path found for "+module+" (check JS_GN_PATH)"
+    raise "No JS path found for "+module+" (if not in Guix check JS_GN_PATH)"
 
 def pylmm_command(guess=None):
     return assert_bin(get_setting("PYLMM_COMMAND",guess))
@@ -147,9 +147,14 @@ def assert_writable_dir(dir):
         fh.close()
         os.remove(fn)
     except IOError:
-        raise Exception('Unable to write test.txt to directory ' + dir )
+        raise Exception('Unable to write test.txt to directory ' + dir)
     return dir
 
+def assert_file(fn):
+    if not valid_file(fn):
+        raise Exception('Unable to find file '+fn)
+    return fn
+
 def mk_dir(dir):
     if not valid_path(dir):
         os.makedirs(dir)
@@ -174,6 +179,9 @@ def locate(name, subdir=None):
     if subdir: sys.stderr.write(subdir)
     raise Exception("Can not locate "+name+" in "+base)
 
+def locate_phewas(name, subdir=None):
+    return locate(name,'/phewas/'+subdir)
+
 def locate_ignore_error(name, subdir=None):
     """
     Locate a static flat file in the GENENETWORK_FILES environment.
@@ -239,15 +247,17 @@ USE_GN_SERVER      = get_setting_bool('USE_GN_SERVER')
 
 GENENETWORK_FILES  = get_setting('GENENETWORK_FILES')
 JS_GUIX_PATH       = get_setting('JS_GUIX_PATH')
-# assert_dir(JS_GUIX_PATH) - don't enforce right now
+assert_dir(JS_GUIX_PATH)
 JS_GN_PATH         = get_setting('JS_GN_PATH')
 # assert_dir(JS_GN_PATH)
 
-PYLMM_COMMAND         = pylmm_command()
-GEMMA_COMMAND         = gemma_command()
+PYLMM_COMMAND      = app_set("PYLMM_COMMAND",pylmm_command())
+GEMMA_COMMAND      = app_set("GEMMA_COMMAND",gemma_command())
+assert(GEMMA_COMMAND is not None)
+PLINK_COMMAND      = app_set("PLINK_COMMAND",plink_command())
 GEMMA_WRAPPER_COMMAND = gemma_wrapper_command()
-PLINK_COMMAND         = plink_command()
-TEMPDIR               = tempdir() # defaults to UNIX TMPDIR
+TEMPDIR            = tempdir() # defaults to UNIX TMPDIR
+assert_dir(TEMPDIR)
 
 # ---- Handle specific JS modules
 JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("Twitter-Post-Fetcher"))
@@ -257,7 +267,7 @@ from six import string_types
 
 if os.environ.get('WQFLASK_OVERRIDES'):
     jsonfn = get_setting('WQFLASK_OVERRIDES')
-    logger.error("WQFLASK_OVERRIDES: %s" % jsonfn)
+    logger.info("WQFLASK_OVERRIDES: %s" % jsonfn)
     with open(jsonfn) as data_file:
         overrides = json.load(data_file)
         for k in overrides:
@@ -267,3 +277,6 @@ if os.environ.get('WQFLASK_OVERRIDES'):
             else:
                 OVERRIDES[k] = cmd
             logger.debug(OVERRIDES)
+
+# assert_file(PHEWAS_FILES+"/auwerx/PheWAS_pval_EMMA_norm.RData")
+assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js")
diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py
index 24432ad0..3d1c0d17 100644
--- a/wqflask/wqflask/correlation/show_corr_results.py
+++ b/wqflask/wqflask/correlation/show_corr_results.py
@@ -75,6 +75,46 @@ 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
@@ -96,7 +136,19 @@ class CorrelationResults(object):
         # get trait list from db (database name)
         # calculate correlation with Base vector and targets
 
-        print("TESTING...")
+        # Check parameters
+        assert('corr_type' in start_vars)
+        assert(is_str(start_vars['corr_type']))
+        assert('dataset' in start_vars)
+        # assert('group' in start_vars) permitted to be empty?
+        assert('corr_sample_method' in start_vars)
+        assert('corr_samples_group' in start_vars)
+        assert('corr_dataset' in start_vars)
+        assert('min_expr' in start_vars)
+        assert('corr_return_results' in start_vars)
+        if 'loc_chr' in start_vars:
+            assert('min_loc_mb' in start_vars)
+            assert('max_loc_mb' in start_vars)
 
         with Bench("Doing correlations"):
             if start_vars['dataset'] == "Temp":
@@ -115,27 +167,17 @@ class CorrelationResults(object):
             self.sample_data = {}
             self.corr_type = start_vars['corr_type']
             self.corr_method = start_vars['corr_sample_method']
-            if 'min_expr' in start_vars:
-                if start_vars['min_expr'] != "":
-                    self.min_expr = float(start_vars['min_expr'])
-                else:
-                    self.min_expr = None
-            self.p_range_lower = float(start_vars['p_range_lower'])
-            self.p_range_upper = float(start_vars['p_range_upper'])
+            self.min_expr = get_float(start_vars,'min_expr')
+            self.p_range_lower = get_float(start_vars,'p_range_lower',-1.0)
+            self.p_range_upper = get_float(start_vars,'p_range_upper',1.0)
 
             if ('loc_chr' in start_vars and
                 'min_loc_mb' in start_vars and
                 'max_loc_mb' in start_vars):
 
-                self.location_chr = start_vars['loc_chr']
-                if start_vars['min_loc_mb'].isdigit():
-                    self.min_location_mb = start_vars['min_loc_mb']
-                else:
-                    self.min_location_mb = None
-                if start_vars['max_loc_mb'].isdigit():
-                    self.max_location_mb = start_vars['max_loc_mb']
-                else:
-                    self.max_location_mb = None
+                self.location_chr = get_string(start_vars,'loc_chr')
+                self.min_location_mb = get_int(start_vars,'min_loc_mb')
+                self.max_location_mb = get_int(start_vars,'max_loc_mb')
 
             self.get_formatted_corr_type()
             self.return_number = int(start_vars['corr_return_results'])
@@ -183,7 +225,7 @@ class CorrelationResults(object):
                 else:
                     for trait, values in self.target_dataset.trait_data.iteritems():
                         self.get_sample_r_and_p_values(trait, values)
-                        
+
             elif self.corr_type == "lit":
                 self.trait_geneid_dict = self.dataset.retrieve_genes("GeneId")
                 lit_corr_data = self.do_lit_correlation_for_all_traits()
@@ -564,7 +606,7 @@ class CorrelationResults(object):
                 self.this_trait_vals.append(sample_value)
                 target_vals.append(target_sample_value)
 
-        self.this_trait_vals, target_vals, num_overlap = corr_result_helpers.normalize_values(self.this_trait_vals, target_vals)	
+        self.this_trait_vals, target_vals, num_overlap = corr_result_helpers.normalize_values(self.this_trait_vals, target_vals)
 
         #ZS: 2015 could add biweight correlation, see http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3465711/
         if self.corr_method == 'pearson':
@@ -574,8 +616,8 @@ class CorrelationResults(object):
 
         if num_overlap > 5:
             self.correlation_data[trait] = [sample_r, sample_p, num_overlap]
-		
-		
+
+
         """
         correlations = []
 
@@ -673,8 +715,8 @@ class CorrelationResults(object):
                         method=self.method)
 
         return trait_list
-        """		
-		
+        """
+
 
     def do_tissue_corr_for_all_traits_2(self):
         """Comments Possibly Out of Date!!!!!
@@ -1089,7 +1131,7 @@ class CorrelationResults(object):
             totalTraits = len(traits) #XZ, 09/18/2008: total trait number
 
         return traits
-			
+
     def calculate_corr_for_all_tissues(self, tissue_dataset_id=None):
 
         symbol_corr_dict = {}
@@ -1129,7 +1171,7 @@ class CorrelationResults(object):
                     values_2.append(target_value)
             correlation = calCorrelation(values_1, values_2)
             self.correlation_data[trait] = correlation
-			
+
     def getFileName(self, target_db_name):  ### dcrowell  August 2008
         """Returns the name of the reference database file with which correlations are calculated.
         Takes argument cursor which is a cursor object of any instance of a subclass of templatePage
@@ -1144,7 +1186,7 @@ class CorrelationResults(object):
         return FileName
 
     def do_parallel_correlation(self, db_filename, num_overlap):
-	
+
         #XZ, 01/14/2009: This method is for parallel computing only.
         #XZ: It is supposed to be called when "Genetic Correlation, Pearson's r" (method 1)
         #XZ: or "Genetic Correlation, Spearman's rho" (method 2) is selected
@@ -1313,7 +1355,7 @@ class CorrelationResults(object):
                         z_value = z_value*math.sqrt(nOverlap-3)
                         sample_p = 2.0*(1.0 - reaper.normp(abs(z_value)))
 
-                correlation_data[traitdataName] = [sample_r, sample_p, nOverlap]	
+                correlation_data[traitdataName] = [sample_r, sample_p, nOverlap]
 
                 # traitinfo = [traitdataName, sample_r, nOverlap]
                 # allcorrelations.append(traitinfo)
@@ -1321,7 +1363,7 @@ class CorrelationResults(object):
             return correlation_data
             # return allcorrelations
 
-	
+
         datasetFile = open(webqtlConfig.GENERATED_TEXT_DIR+db_filename,'r')
 
         print("Invoking parallel computing")
@@ -1378,5 +1420,3 @@ class CorrelationResults(object):
         # for one_result in results:
             # for one_traitinfo in one_result:
                 # allcorrelations.append( one_traitinfo )
-
-
diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py
index a24e43d4..68920130 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
+from utility.tools import flat_files, GEMMA_COMMAND, GEMMA_WRAPPER_COMMAND, TEMPDIR, assert_bin, assert_file
 
 import utility.logger
 logger = utility.logger.getLogger(__name__ )
@@ -11,6 +11,7 @@ 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:
@@ -27,7 +28,7 @@ def run_gemma(this_dataset, samples, vals, covariates, method, use_loco):
         if i < (len(this_chromosomes) - 1):
             chr_list_string += this_chromosomes[i+1].name + ","
         else:
-            chr_list_string += this_chromosomes[i+1].name  
+            chr_list_string += this_chromosomes[i+1].name
 
     if covariates != "":
         gen_covariates_file(this_dataset, covariates)
@@ -209,8 +210,13 @@ def parse_gemma_output(genofile_name):
 def parse_loco_output(this_dataset, gwa_output_filename):
 
     output_filelist = []
-    with open("{}/gn2/".format(TEMPDIR) + gwa_output_filename + ".json") as data_file:
-       data = json.load(data_file)
+    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)
 
     files = data['files']
     for file in files:
@@ -247,4 +253,4 @@ def parse_loco_output(this_dataset, gwa_output_filename):
                     included_markers.append(line.split("\t")[1])
                     p_values.append(float(line.split("\t")[10]))
 
-    return marker_obs
\ No newline at end of file
+    return marker_obs
diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py
index bcb14451..087b95b4 100644
--- a/wqflask/wqflask/marker_regression/marker_regression.py
+++ b/wqflask/wqflask/marker_regression/marker_regression.py
@@ -79,6 +79,16 @@ class MarkerRegression(object):
                     self.samples.append(sample)
                     self.vals.append(value)
 
+        #ZS: Check if genotypes exist in the DB in order to create links for markers
+        if "geno_db_exists" in start_vars:
+            self.geno_db_exists = start_vars['geno_db_exists']
+        else:
+          try:
+            geno_dataset = data_set.create_dataset(self.dataset.group.name + "Geno")
+            self.geno_db_exists = "True"
+          except:
+            self.geno_db_exists = "False"
+
         self.mapping_method = start_vars['method']
         if "results_path" in start_vars:
             self.mapping_results_path = start_vars['results_path']
diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py
index 93bd9d42..211cf187 100644
--- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py
+++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py
@@ -174,6 +174,8 @@ class MarkerRegression(object):
         if 'genofile_string' in start_vars:
             self.genofile_string = start_vars['genofile_string']
 
+        self.geno_db_exists = start_vars['geno_db_exists']
+
         #Needing for form submission when doing single chr mapping or remapping after changing options
         self.samples = start_vars['samples']
         self.vals = start_vars['vals']
@@ -576,7 +578,7 @@ class MarkerRegression(object):
         self.gifmap = gifmap.__str__()
 
         self.filename= webqtlUtil.genRandStr("Itvl_")
-        intCanvas.save(os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename), format='jpeg')
+        intCanvas.save(os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename), format='png')
         intImg=HT.Image('/image/'+self.filename+'.png', border=0, usemap='#WebQTLImageMap')
 
         #Scales plot differently for high resolution
@@ -616,7 +618,7 @@ class MarkerRegression(object):
         else:
             showLocusForm = intImg
 
-        if self.permChecked and self.nperm > 0 and not self.multipleInterval and 0 < self.nperm:
+        if (self.permChecked and self.nperm > 0) and not (self.multipleInterval and 0 < self.nperm):
             self.perm_filename = self.drawPermutationHistogram()
             #perm_text_file = self.permutationTextFile()
 
@@ -1200,8 +1202,10 @@ class MarkerRegression(object):
         if self.controlLocus and self.doControl != "false":
             string2 = 'Using %s as control' % self.controlLocus
         else:
-            if self.mapping_method == "gemma":
+            if self.mapping_method == "gemma" or self.mapping_method == "gemma_bimbam":
                 string2 = 'Using GEMMA mapping method with no control for other QTLs.'
+            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":
                 string2 = 'Using PLINK mapping method with no control for other QTLs.'
             else:
@@ -1963,6 +1967,8 @@ class MarkerRegression(object):
 
             if self.permChecked and self.nperm > 0 and not self.multipleInterval:
                 LRS_LOD_Max = max(self.significant, LRS_LOD_Max)
+            else:
+                LRS_LOD_Max = 1.15*LRS_LOD_Max
 
             #genotype trait will give infinite LRS
             LRS_LOD_Max = min(LRS_LOD_Max, webqtlConfig.MAXLRS)
@@ -2164,10 +2170,7 @@ class MarkerRegression(object):
                 #    Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/LRS_LOD_Max
 
                 if self.manhattan_plot == True:
-                    if previous_chr_as_int % 2 == 1:
-                        point_color = pid.grey
-                    else:
-                        point_color = pid.black
+                    point_color = pid.black
                     canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=point_color, font=symbolFont)
                 else:
                     LRSCoordXY.append((Xc, Yc))
diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json
index 8de85a86..b7ebb9ed 100644
--- a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json
+++ b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json
@@ -2974,6 +2974,20 @@
                ]
             ]
          },
+         "BXD-Harvested": {
+            "Liver mRNA": [
+               [
+                  "843",
+                  "UTHSC-BXD-Harv_Liv-0118",
+                  "UTHSC BXD Harvested Liver RNA-Seq (Jan18) Log2 **"
+               ],
+               [
+                  "842",
+                  "UTHSC-BXD-Liv-0917",
+                  "UTHSC BXD Liver Affy Clariom S GeneLevel Main (Sep17) RMA **"
+               ]
+            ]
+         },
          "BXD300": {
             "Genotypes": [
                [
@@ -3864,6 +3878,10 @@
             "BXD Bone"
          ],
          [
+            "BXD-Harvested",
+            "BXD NIA Longevity Study"
+         ],
+         [
             "BXD300",
             "BXD300"
          ],
@@ -5007,6 +5025,12 @@
                "Phenotypes"
             ]
          ],
+         "BXD-Harvested": [
+            [
+               "Liver mRNA",
+               "Liver mRNA"
+            ]
+         ],
          "BXD300": [
             [
                "Phenotypes",
diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
index 2f1d836a..4d98f5d8 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
@@ -245,6 +245,7 @@
       //$("#static_progress_bar_container").modal();
       url = "/loading";
       $('input[name=method]').val("gemma_bimbam");
+      $('input[name=num_perm]').val(0);
       $('input[name=genofile]').val($('#genofile_gemma').val());
       $('input[name=maf]').val($('input[name=maf_gemma]').val());
       form_data = $('#trait_data_form').serialize();
diff --git a/wqflask/wqflask/templates/loading.html b/wqflask/wqflask/templates/loading.html
index cede0e86..46136ddb 100644
--- a/wqflask/wqflask/templates/loading.html
+++ b/wqflask/wqflask/templates/loading.html
@@ -1,20 +1,20 @@
 <title>Loading Mapping Results</title>
 <link REL="stylesheet" TYPE="text/css" href="/static/packages/bootstrap/css/bootstrap.css" />
-<link REL="stylesheet" TYPE="text/css" href="/static/packages/bootstrap/css/non-responsive.css" />
-<link REL="stylesheet" TYPE="text/css" href="/static/packages/bootstrap/css/docs.css" />
-<link rel="stylesheet" type="text/css" href="/static/packages/colorbox/example4/colorbox.css"  />
-<link rel="stylesheet" type="text/css" href="/static/new/css/main.css"  />
 <form method="post" action="/marker_regression" name="loading_form" id="loading_form" class="form-horizontal">
   {% for key, value in start_vars.iteritems() %}
   <input type="hidden" name="{{ key }}" value="{{ value }}">
   {% endfor %}
   <div class="container">
-    <div class="row">
-      <div style="margin-left: 46%; margin-right: 50%; min-height: 100vh; display: flex; align-items: center;">
-        <h1>Loading&nbsp;Mapping&nbsp;Results...</h1>
+    <div>
+      <div style="min-height: 80vh; display: flex; align-items: center;">
+        <div class="center-block" style="margin-left: 38%; margin-right: 38%; position: absolute; height:50px; width:24%; top:40%;">
+          <h1>Loading&nbsp;Mapping&nbsp;Results...</h1>
+        </div>
       </div>
-      <div class="progress center-block" style="margin-left: 25%; margin-right: 25%; position: absolute; height:50px; width:50%; top:50%;">
-        <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width:100%;"></div>
+      <div style="min-height: 80vh; display: flex; align-items: center;">
+        <div class="progress center-block" style="margin-left: 25%; margin-right: 25%; position: absolute; height:50px; width:50%; top:50%;">
+          <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width:100%;"></div>
+        </div>
       </div>
     </div>
   </div>
diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/marker_regression_gn1.html
index d13c68cd..08a934a6 100644
--- a/wqflask/wqflask/templates/marker_regression_gn1.html
+++ b/wqflask/wqflask/templates/marker_regression_gn1.html
@@ -15,6 +15,7 @@
         <input type="hidden" name="trait_id" value="{{ this_trait.name }}">
         <input type="hidden" name="dataset" value="{{ dataset.name }}">
         <input type="hidden" name="genofile" value="{{ genofile_string }}">
+        <input type="hidden" name="geno_db_exists" value="{{ geno_db_exists }}">
         <input type="hidden" name="results_path" value="{{ mapping_results_path }}">
         <input type="hidden" name="method" value="{{ mapping_method }}">
         {% for sample in samples %}
@@ -154,7 +155,7 @@
             <div class="tab-pane active" id="gn1_map">
               <div class="qtlcharts">
                   {{ gifmap|safe }}
-                  <img src="/generated/{{ filename }}.jpeg" usemap="#WebQTLImageMap">
+                  <img src="/generated/{{ filename }}.png" usemap="#WebQTLImageMap">
                   {% if additiveChecked|upper == "ON" %}
                   <br>
                   <span style="white-space: nowrap;">A positive additive coefficient (green line) indicates that {{ dataset.group.parlist[1] }} alleles increase trait values. In contrast, a negative additive coefficient (orange line) indicates that {{ dataset.group.parlist[0] }} alleles increase trait values.</span>
@@ -180,10 +181,10 @@
 
         </form>
         {% if selectedChr == -1 %}
-        <div style="width:{% if 'additive' in trimmed_markers[0] %}45%{% else %}35%{% endif %};">
-          <h2>Results</h2>
-          <div id="table_container">
-          <table id="qtl_results" class="table table-hover table-striped nowrap">
+        <div class="container" style="padding-left: 30px; width:{% if 'additive' in trimmed_markers[0] %}45%{% else %}35%{% endif %};">
+          <h2>Mapping Statistics</h2>
+          <div id="table_container" style="border-style: solid; border-width: 1px; border-color: black;">
+          <table id="trait_table" class="table table-hover table-striped nowrap">
             <thead>
               <tr>
                 <th></th>
@@ -194,7 +195,7 @@
                 {% if plotScale != "physic" %}
                 <th>cM</th>
                 {% else %}
-                <th>Mb</th>
+                <th align="right">Mb</th>
                 {% endif %}
                 {% if 'additive' in trimmed_markers[0] %}
                 <th>Add Eff</th>
@@ -209,11 +210,11 @@
               <tr>
                 <td align="center" style="padding-right: 0px;">
                   <input type="checkbox" name="selectCheck"
-                         class="checkbox edit_sample_checkbox"
-                         value="{{ marker.name }}" checked="checked">
+                         class="checkbox trait_checkbox"
+                         value="{{ marker.name }}">
                 </td>
                 <td align="right">{{ loop.index }}</td>
-                <td>{{ marker.name }}</td>
+                <td>{% if geno_db_exists == "True" %}<a href="/show_trait?trait_id={{ marker.name }}&dataset={{ dataset.group.name }}Geno">{{ marker.name }}</a>{% else %}{{ marker.name }}{% endif %}</td>
                 {% if LRS_LOD == "LOD" or LRS_LOD == "-log(p)" %}
                 {% if 'lod_score' in marker %}
                 <td align="right">{{ '%0.2f' | format(marker.lod_score|float) }}</td>
@@ -294,6 +295,7 @@
     </script>
     {% endif %}
 
+    <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
     {% if mapping_method != "gemma" and mapping_method != "plink" %}
     <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/javascript/chr_lod_chart.js"></script> 
@@ -304,7 +306,7 @@
     <script type="text/javascript" charset="utf-8">
         $(document).ready( function () {
             console.time("Creating table");
-            $('#qtl_results').DataTable( {
+            $('#trait_table').DataTable( {
                 {% if mapping_method != "reaper" %}
                 "columns": [
                     { "type": "natural", "width": "5%" },
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index a291baf3..dd4325e7 100644
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -28,7 +28,9 @@
 -->
     <div class="container">
         <h2>Trait Data and Analysis for <b>{{ this_trait.name }}</b></h2>
+        {% if this_trait.dataset.type != 'Publish' %}
         <h3>{{ this_trait.description_fmt }}</h3>
+        {% endif %}
     </div>
 
     <form method="post" action="/corr_compute" target="_blank" name="trait_page" id="trait_data_form"
diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html
index 2a62733e..1e6d41c2 100644
--- a/wqflask/wqflask/templates/show_trait_details.html
+++ b/wqflask/wqflask/templates/show_trait_details.html
@@ -8,6 +8,22 @@
         <td>Tissue</td>
         <td>{{ this_trait.dataset.tissue }}</td>
     </tr>
+    <tr>
+        <td>Phenotype</td>
+        <td><div style="width:40%;">{{ this_trait.description_fmt }}</div></td>
+    </tr>
+    <tr>
+        <td>Authors</td>
+        <td><div style="width:40%;">{{ this_trait.authors }}</div></td>
+    </tr>
+    <tr>
+        <td>Title</td>
+        <td><div style="width:40%;">{{ this_trait.title }}</div></td>
+    </tr>
+    <tr>
+        <td>Journal</td>
+        <td>{{ this_trait.journal }} (<a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids={{ this_trait.pubmed_id }}&dop=Abstract" title="PubMed">{{ this_trait.year }}</a>)</td>
+    </tr>
     {% endif %}
     {% if this_trait.dataset.type == 'ProbeSet' %}
     {% if this_trait.symbol != None %}
@@ -50,22 +66,29 @@
         </td>
     </tr>
     {% endif %}
+    {% if this_trait.pubmed_id or this_trait.geneid or this_trait.omim or this_trait.symbol %}
+    {% if this_trait.dataset.type != 'Publish' %}
     <tr>
         <td>Resource Links</td>
         <td>
-            {% if this_trait.geneid != None %}
+            {% if this_trait.pubmed_id %}
+            <a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids={{ this_trait.pubmed_id }}&dop=Abstract" title="PubMed">
+                PubMed
+            </a>
+            {% endif %}
+            {% if this_trait.geneid %}
             <a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids={{ this_trait.geneid }}" title="Info from NCBI Entrez Gene">
                 NCBI
             </a>
             &nbsp;&nbsp;
             {% endif %}
-            {% if this_trait.omim != None %}
+            {% if this_trait.omim %}
             <a href="http://www.ncbi.nlm.nih.gov/omim/{{ this_trait.omim }}" title="Summary from On Mendelion Inheritance in Man">
                 OMIM
             </a>
             &nbsp;&nbsp;
             {% endif %}
-            {% if this_trait.symbol != None %}
+            {% if this_trait.symbol %}
             <a href="http://www.genotation.org/Getd2g.pl?gene_list={{ this_trait.symbol }}" title="Related descriptive, genomic, clinical, functional and drug-therapy information">
                 Genotation
             </a>
@@ -77,6 +100,8 @@
         {% endif %}
         </td>
     </tr>
+    {% endif %}
+    {% endif %}
 </table>
 
 <div style="margin-bottom:15px;" class="btn-toolbar">
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index 77f78415..dcec2b9e 100644
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -6,16 +6,16 @@
             <ul class="nav nav-pills">
                 {% if dataset.group.mapping_id == "1" %}
                 <li class="active">
-                    <a href="#interval_mapping" data-toggle="tab">Interval Mapping</a>
+                    <a href="#gemma" data-toggle="tab">GEMMA</a>
                 </li>
                 <li>
-                    <a href="#pylmm" data-toggle="tab">pyLMM</a>
+                    <a href="#interval_mapping" data-toggle="tab">Interval Mapping</a>
                 </li>
                 <li>
                     <a href="#rqtl_geno" data-toggle="tab">R/qtl</a>
                 </li>
                 <li>
-                    <a href="#gemma" data-toggle="tab">GEMMA</a>
+                    <a href="#pylmm" data-toggle="tab">pyLMM</a>
                 </li>
                 {% endif %}
                 {% for mapping_method in dataset.group.mapping_names %}
@@ -37,7 +37,60 @@
             <div class="tab-content">
                 {# 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="interval_mapping">
+                <div class="tab-pane active" id="gemma">
+                    <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">
+                                <select id="genofile_gemma" class="form-control">
+                                    {% for item in genofiles %}
+                                    <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+                                    {% endfor %}
+                                </select>
+                            </div>
+                        </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">
+                                <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 class="radio-inline">
+                                    <input type="radio" name="use_loco" value="True">
+                                    Yes
+                                </label>
+                                <label class="radio-inline">
+                                    <input type="radio" name="use_loco" value="False" checked="">
+                                    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
+                            </button>
+                        </div>
+                    </div>
+
+                    <div class="form-group">
+                        <div class="col-xs-4 controls">
+                            <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="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">
@@ -131,62 +184,6 @@
                         <!--<div id="alert_placeholder"></div>-->
                     </div>
                 </div>
-                <div class="tab-pane" id="pylmm">
-                    <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">
-                                <select id="genofile_pylmm" class="form-control">
-                                    {% for item in genofiles %}
-                                    <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
-                                    {% endfor %}
-                                </select>
-                            </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>
-                            </div>
-                        </div>
-                    </div>
-                </div>
                 <div class="tab-pane" id="rqtl_geno">
 
                     <div style="margin-top: 20px" class="form-horizontal">
@@ -294,13 +291,13 @@
                         </div>
                     </div>
                 </div>
-                <div class="tab-pane" id="gemma">
-                    <div style="padding-top: 10px;" class="form-horizontal">
+                <div class="tab-pane" id="pylmm">
+                    <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">
-                                <select id="genofile_gemma" class="form-control">
+                                <select id="genofile_pylmm" class="form-control">
                                     {% for item in genofiles %}
                                     <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
                                     {% endfor %}
@@ -308,42 +305,45 @@
                             </div>
                         </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">
-                                <input name="maf_gemma" value="0.01" type="text" class="form-control">
+                            <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 class="col-xs-4 control-label">Use LOCO</label>
-                            <div style="margin-left: 20px;" class="col-xs-4 controls">
+                            <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="use_loco" value="True">
+                                    <input type="radio" name="manhattan_plot_pylmm" value="True">
                                     Yes
                                 </label>
                                 <label class="radio-inline">
-                                    <input type="radio" name="use_loco" value="False" checked="">
+                                    <input type="radio" name="manhattan_plot_pylmm" value="False" checked="">
                                     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
-                            </button>
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <div class="col-xs-4 controls">
-                            <button id="gemma_bimbam_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression">
-                                Compute
-                            </button>
+-->
+                        <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>
+                            </div>
                         </div>
                     </div>
                 </div>
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index 68e779a1..4e81c29c 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -557,6 +557,7 @@ def marker_regression_page():
     wanted = (
         'trait_id',
         'dataset',
+        'geno_db_exists',
         'method',
         'mapping_results_path',
         'trimmed_markers',
@@ -765,7 +766,7 @@ def corr_scatter_plot_page():
 def submit_bnw():
     logger.error(request.url)
     template_vars = get_bnw_input(request.form)
-    return render_template("empty_collection.html", **{'tool':'Correlation Matrix'}) 
+    return render_template("empty_collection.html", **{'tool':'Correlation Matrix'})
 
 # Todo: Can we simplify this? -Sam
 def sharing_info_page():
diff --git a/wqflask/wsgi.py b/wqflask/wsgi.py
new file mode 100644
index 00000000..be9c7b37
--- /dev/null
+++ b/wqflask/wsgi.py
@@ -0,0 +1,4 @@
+from run_gunicorn import app as application # expect application as a name
+
+if __name__ == "__main__":
+    application.run()