about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/database.org165
-rw-r--r--etc/default_settings.py19
-rw-r--r--wqflask/runserver.py11
-rw-r--r--wqflask/utility/logger.py2
-rw-r--r--wqflask/utility/tools.py13
-rw-r--r--wqflask/wqflask/static/new/javascript/biodalliance.js72
-rw-r--r--wqflask/wqflask/static/new/javascript/chr_lod_chart.coffee37
-rw-r--r--wqflask/wqflask/static/new/javascript/chr_lod_chart.js31
-rw-r--r--wqflask/wqflask/static/new/javascript/create_lodchart.coffee16
-rw-r--r--wqflask/wqflask/static/new/javascript/create_lodchart.js11
-rw-r--r--wqflask/wqflask/static/new/javascript/lod_chart.coffee2
-rw-r--r--wqflask/wqflask/static/new/javascript/lod_chart.js63
-rw-r--r--wqflask/wqflask/templates/marker_regression_gn1.html210
-rw-r--r--wqflask/wqflask/views.py54
14 files changed, 556 insertions, 150 deletions
diff --git a/doc/database.org b/doc/database.org
index 624174a4..5107b660 100644
--- a/doc/database.org
+++ b/doc/database.org
@@ -1,9 +1,19 @@
-- github Document reduction issue
+* Database Information
+
+WARNING: This document contains information on the GN databases which
+will change over time. The GN database is currently MySQL based and,
+while efficient, contains a number of design choices we want to grow
+'out' of. Especially with an eye on reproducibility we want to
+introduce versioning.
+
+So do not treat the information in this document as a final way of
+accessing data. It is better to use the
+[[https://github.com/genenetwork/gn_server/blob/master/doc/API.md][REST API]].
 
 * The small test database (2GB)
 
 The default install comes with a smaller database which includes a
-number of the BSD's and the Human liver dataset (GSE9588).
+number of the BXD's and the Human liver dataset (GSE9588).
 
 * GeneNetwork database
 
@@ -750,9 +760,30 @@ show indexes from ProbeSetFreeze;
 |      1 |        5 | 0.303492 |
 +--------+----------+----------+
 
-** Publication and publishdata (all pheno)
+** Publication
+
+Publication:
+
+| Id   | PubMed_ID | Abstract    | Title   | Pages   | Month | Year |
+
 
-Phenotype pubs
+** Publishdata (all pheno)
+
+One of three phenotype tables.
+
+mysql> select * from PublishData limit 5;
++---------+----------+-------+
+| Id      | StrainId | value |
++---------+----------+-------+
+| 8966353 |      349 |  29.6 |
+| 8966353 |      350 |  27.8 |
+| 8966353 |      351 |  26.6 |
+| 8966353 |      352 |  28.5 |
+| 8966353 |      353 |  24.6 |
++---------+----------+-------+
+5 rows in set (0.25 sec)
+
+See below for phenotype access.
 
 ** QuickSearch
 
@@ -1073,7 +1104,37 @@ select * from ProbeSetXRef limit 5;
 i.e., for Strain Id 1 (DataId) 1, the locus '10.095.400' has a
 phenotype value of 5.742.
 
-GeneNetwork1 already has a limited REST interface, if you do
+Interestingly ProbeData and PublishData have the same layout as
+ProbeSetData. ProbeData is only in use for Affy assays - and not used
+for computations. PublishData contains trait values. ProbeSetData.id
+matches ProbeSetXRef.DataId while PublishData.id matches
+PublishXRef.DataId.
+
+select * from PublishXRef limit 3;
++-------+-------------+-------------+---------------+---------+----------------+------------------+-----------+----------+-------------------------------------------------------+
+| Id    | InbredSetId | PhenotypeId | PublicationId | DataId  | Locus          | LRS              | additive  | Sequence | comments                                              |
++-------+-------------+-------------+---------------+---------+----------------+------------------+-----------+----------+-------------------------------------------------------+
+| 10001 |           8 |           1 |             1 | 8966353 | D2Mit5         |   10.18351644706 |  -1.20875 |        1 |                                                       |
+| 10001 |           7 |           2 |            53 | 8966813 | D7Mit25UT      | 9.85534330983917 |  -2.86875 |        1 |                                                       |
+| 10001 |           4 |           3 |            81 | 8966947 | CEL-6_57082524 | 11.7119505898121 | -23.28875 |        1 | elissa modified Abstract at Tue Jun  7 11:38:00 2005  |
++-------+-------------+-------------+---------------+---------+----------------+------------------+-----------+----------+-------------------------------------------------------+
+3 rows in set (0.00 sec)
+
+ties the trait data (PublishData) with the inbredsetid (matching
+PublishFreeze.InbredSetId), locus and publication.
+
+select * from PublishFreeze -> ;
++----+------------+--------------------------+-------------+------------+--------+-------------+-----------------+-----------------+
+| Id | Name       | FullName                 | ShortName   | CreateTime | public | InbredSetId | confidentiality | AuthorisedUsers |
++----+------------+--------------------------+-------------+------------+--------+-------------+-----------------+-----------------+
+|  1 | BXDPublish | BXD Published Phenotypes | BXDPublish  | 2004-07-17 |      2 |           1 |               0 | NULL            |
+| 18 | HLCPublish | HLC Published Phenotypes | HLC Publish | 2012-02-20 |      2 |          34 |               0 | NULL            |
++----+------------+--------------------------+-------------+------------+--------+-------------+-----------------+-----------------+
+2 rows in set (0.02 sec)
+
+which gives us the datasets.
+
+GeneNetwork1 has a limited REST interface, if you do
 
 : curl "http://robot.genenetwork.org/webqtl/main.py?cmd=get&probeset=1443823_s_at&db=HC_M2_0606_P"
 
@@ -1082,6 +1143,9 @@ we get
 : ProbeSetID      B6D2F1  C57BL/6J        DBA/2J  BXD1    BXD2    BXD5    BXD6   BXD8     BXD9    BXD11   BXD12   BXD13   BXD15   BXD16   BXD19   BXD20   BXD21  BXD22    BXD23   BXD24   BXD27   BXD28   BXD29   BXD31   BXD32   BXD33   BXD34  BXD38    BXD39   BXD40   BXD42   BXD67   BXD68   BXD43   BXD44   BXD45   BXD48  BXD50    BXD51   BXD55   BXD60   BXD61   BXD62   BXD63   BXD64   BXD65   BXD66  BXD69    BXD70   BXD73   BXD74   BXD75   BXD76   BXD77   BXD79   BXD73a  BXD83  BXD84    BXD85   BXD86   BXD87   BXD89   BXD90   BXD65b  BXD93   BXD94   A/J    AKR/J    C3H/HeJ C57BL/6ByJ      CXB1    CXB2    CXB3    CXB4    CXB5    CXB6   CXB7     CXB8    CXB9    CXB10   CXB11   CXB12   CXB13   BXD48a  129S1/SvImJ    BALB/cJ  BALB/cByJ       LG/J    NOD/ShiLtJ      PWD/PhJ BXD65a  BXD98   BXD99  CAST/EiJ KK/HlJ  WSB/EiJ NZO/HlLtJ       PWK/PhJ D2B6F1
 : 1443823_s_at    15.251  15.626  14.716  15.198  14.918  15.057  15.232  14.968 14.87    15.084  15.192  14.924  15.343  15.226  15.364  15.36   14.792  14.908 15.344   14.948  15.08   15.021  15.176  15.14   14.796  15.443  14.636  14.921 15.22    15.62   14.816  15.39   15.428  14.982  15.05   15.13   14.722  14.636 15.242   15.527  14.825  14.416  15.125  15.362  15.226  15.176  15.328  14.895 15.141   15.634  14.922  14.764  15.122  15.448  15.398  15.089  14.765  15.234 15.302   14.774  14.979  15.212  15.29   15.012  15.041  15.448  14.34   14.338 14.809   15.046  14.816  15.232  14.933  15.255  15.21   14.766  14.8    15.506 15.749   15.274  15.599  15.673  14.651  14.692  14.552  14.563  14.164  14.546 15.044   14.695  15.162  14.772  14.645  15.493  14.75   14.786  15.003  15.148 15.221
 
+(see https://github.com/genenetwork/gn_server/blob/master/doc/API.md
+for the latest REST API).
+
 getTraitData is defined in the file [[https://github.com/genenetwork/genenetwork/blob/master/web/webqtl/textUI/cmdClass.py#L134][web/webqtl/textUI/cmdClass.py]].
 probe is None, so the code at line 199 is run
 
@@ -1165,6 +1229,97 @@ select * from ProbeSetData limit 5;
 5 rows in set (0.00 sec)
 
 linked by ProbeSetXRef.dataid.
+
+*** For PublishData:
+
+List datasets for BXD (InbredSetId=1):
+
+select * from PublishXRef where InbredSetId=1 limit 3;
++-------+-------------+-------------+---------------+---------+-----------+------------------+------------------+----------+--------------------------------------------------------------------------------+
+| Id    | InbredSetId | PhenotypeId | PublicationId | DataId  | Locus     | LRS              | additive         | Sequence | comments                                                                       |
++-------+-------------+-------------+---------------+---------+-----------+------------------+------------------+----------+--------------------------------------------------------------------------------+
+| 10001 |           1 |           4 |           116 | 8967043 | rs8253516 | 13.4974914158039 | 2.39444444444444 |        1 | robwilliams modified post_publication_description at Mon Jul 30 14:58:10 2012
+ |
+| 10002 |           1 |          10 |           116 | 8967044 | rs3666069 | 22.0042692151629 | 2.08178571428572 |        1 | robwilliams modified phenotype at Thu Oct 28 21:43:28 2010
+                    |
+| 10003 |           1 |          15 |           116 | 8967045 | D18Mit4   | 15.5929163293343 | 19.0882352941176 |        1 | robwilliams modified phenotype at Mon May 23 20:52:19 2011
+                    |
++-------+-------------+-------------+---------------+---------+-----------+------------------+------------------+----------+--------------------------------------------------------------------------------+
+
+where ID is the 'record' or, effectively, dataset.
+
+select distinct(publicationid) from PublishXRef where InbredSetId=1 limit 3;
++---------------+
+| publicationid |
++---------------+
+|           116 |
+|           117 |
+|           118 |
++---------------+
+
+select distinct
+PublishXRef.id,publicationid,phenotypeid,Phenotype.post_publication_description
+from PublishXRef,Phenotype where InbredSetId=1 and
+phenotypeid=Phenotype.id limit 3;
++-------+---------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
+| id    | publicationid | phenotypeid | post_publication_description                                                                                               |
++-------+---------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
+| 10001 |           116 |           4 | Central nervous system, morphology: Cerebellum weight [mg]                                                                 |
+| 10002 |           116 |          10 | Central nervous system, morphology: Cerebellum weight after adjustment for covariance with brain size [mg]                 |
+| 10003 |           116 |          15 | Central nervous system, morphology: Brain weight, male and female adult average, unadjusted for body weight, age, sex [mg] |
++-------+---------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
+
+The id field is the same that is used in the GN2 web interface and the
+PublicationID ties the datasets together.
+
+To list trait values:
+
+SELECT Strain.Name, PublishData.id, PublishData.value from
+(Strain,PublishData, PublishXRef) Where PublishData.StrainId =
+Strain.id limit 3;
+
++------+---------+-------+
+| Name | id      | value |
++------+---------+-------+
+| CXB1 | 8966353 |  29.6 |
+| CXB1 | 8966353 |  29.6 |
+| CXB1 | 8966353 |  29.6 |
++------+---------+-------+
+
+here id should match dataid again:
+
+SELECT Strain.Name, PublishData.id, PublishData.value from
+(Strain,PublishData, PublishXRef) Where PublishData.StrainId =
+Strain.id and PublishXRef.dataid=8967043 and
+PublishXRef.dataid=PublishData.id limit 3;
++------+---------+-------+
+| Name | id      | value |
++------+---------+-------+
+| BXD1 | 8967043 |  61.4 |
+| BXD2 | 8967043 |    49 |
+| BXD5 | 8967043 |  62.5 |
++------+---------+-------+
+
+*** Datasets
+
+The REST API aims to present a unified interface for genotype and
+phenotype data. Phenotype datasets appear in two major forms in the
+database and we want to present them as one resource.
+
+Dataset names are defined in ProbeSetFreeze.name and Published.id ->
+publication (we'll ignore the probe dataset that uses
+ProbeFreeze.name). These tables should be meshed. It looks like the
+ids are non-overlapping with the publish record IDs starting at 10,001
+(someone has been smart, though it sets the limit of probesets now to
+10,000).
+
+The datasets are organized differently in these tables. All published
+BXD data is grouped on BXDpublished with the publications as
+'datasets'. So, that is how we list them in the REST API.
+
+To fetch all the datasets we first list ProbeSetFreeze entries. Then
+we list the Published entries.
+
 ** Fetch genotype information
 
 *** SNPs
diff --git a/etc/default_settings.py b/etc/default_settings.py
index 6acea637..08eae024 100644
--- a/etc/default_settings.py
+++ b/etc/default_settings.py
@@ -2,18 +2,22 @@
 # webserver running in developer mode with limited console
 # output. Copy this file and run it from ./bin/genenetwork2 configfile
 #
-# Note that these settings are fetched in ./wqflask/utilities/tools.py
+# Note: these settings are fetched in ./wqflask/utilities/tools.py
 # which has support for overriding them through environment variables,
 # e.g.
 #
 #   env LOG_SQL=True USE_REDIS=False ./bin/genenetwork2
 #   env LOG_LEVEL=DEBUG ./bin/genenetwork2 ~/gn2_settings.py
 #
-# Note also that in the near future we will additionally fetch
+# Note: in the near future we will additionally fetch
 # settings from a JSON file
 #
-# Note that values for False and 0 have to be strings here - otherwise
+# Note: values for False and 0 have to be strings here - otherwise
 # Flask won't pick them up
+#
+# For GNU Guix deployment also check the paths in
+#
+#  ~/.guix-profile/lib/python2.7/site-packages/genenetwork2-2.0-py2.7.egg/etc/default_settings.py
 
 import os
 import sys
@@ -22,7 +26,7 @@ GN_VERSION = open("../VERSION","r").read()
 SQL_URI = "mysql://gn2:mysql_password@localhost/db_webqtl_s"
 SQLALCHEMY_DATABASE_URI = 'mysql://gn2:mysql_password@localhost/db_webqtl_s'
 SQLALCHEMY_POOL_RECYCLE = 3600
-GN_SERVER_URL = "http://localhost:8880/"
+GN_SERVER_URL = "http://test-gn2.genenetwork.org/"
 
 # ---- Flask configuration (see website)
 TRAP_BAD_REQUEST_ERRORS = True
@@ -33,7 +37,7 @@ SECURITY_RECOVERABLE = True
 SECURITY_EMAIL_SENDER = "no-reply@genenetwork.org"
 SECURITY_POST_LOGIN_VIEW = "/thank_you"
 
-SERVER_PORT = 5003
+SERVER_PORT = 5003          # running on localhost
 SECRET_HMAC_CODE = '\x08\xdf\xfa\x93N\x80\xd9\\H@\\\x9f`\x98d^\xb4a;\xc6OM\x946a\xbc\xfc\x80:*\xebc'
 
 # ---- Behavioural settings (defaults) note that logger and log levels can
@@ -41,6 +45,7 @@ SECRET_HMAC_CODE = '\x08\xdf\xfa\x93N\x80\xd9\\H@\\\x9f`\x98d^\xb4a;\xc6OM\x946a
 WEBSERVER_MODE  = 'DEV'     # Python webserver mode (DEBUG|DEV|PROD)
 WEBSERVER_BRANDING = None   # Set the branding (nyi)
 WEBSERVER_DEPLOY = None     # Deployment specifics (nyi)
+WEBSERVER_URL    = "http://localhost:"+str(SERVER_PORT)+"/" # external URL
 
 LOG_LEVEL       = 'WARNING' # Logger mode (DEBUG|INFO|WARNING|ERROR|CRITICAL)
 LOG_LEVEL_DEBUG = '0'       # logger.debugf log level (0-5, 5 = show all)
@@ -53,7 +58,8 @@ USE_GN_SERVER   = 'False'   # Use GN_SERVER SQL calls
 
 # Paths to JS libraries
 
-TWITTER_POST_FETCHER_JS_PATH = os.environ['HOME']+"/genenetwork/Twitter-Post-Fetcher"
+JS_BIODALLIANCE = os.environ['HOME']+"/genenetwork/biodalliance"
+JS_TWITTER_POST_FETCHER = os.environ['HOME']+"/genenetwork/Twitter-Post-Fetcher"
 
 # ---- Path overrides for Genenetwork
 # TMPDIR is normally picked up from the environment
@@ -63,6 +69,7 @@ GENENETWORK_FILES = HOME+"/gn2_data"  # base dir for all static data files
 LOCAL_PRIVATE_FILES = HOME+"/gn2_private_data" # private static data files
 
 # ---- GN2 Executables
+# Paths to invoked binaries
 PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read())
 PLINK_COMMAND = str.strip(os.popen("which plink2").read())
 GEMMA_COMMAND = str.strip(os.popen("which gemma").read())
diff --git a/wqflask/runserver.py b/wqflask/runserver.py
index 0342b7ad..adacc712 100644
--- a/wqflask/runserver.py
+++ b/wqflask/runserver.py
@@ -19,11 +19,18 @@ 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
 
 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+"]")
+
+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 c28c617a..82ef136f 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -121,9 +121,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)
@@ -235,4 +240,8 @@ if os.environ.get('WQFLASK_OVERRIDES'):
                 OVERRIDES[k] = cmd
             logger.debug(OVERRIDES)
 
-assert_dir(get_setting("TWITTER_POST_FETCHER_JS_PATH"))
+assert_dir(get_setting("JS_BIODALLIANCE"))
+assert_file(get_setting("JS_BIODALLIANCE")+"/build/dalliance-all.js")
+assert_file(get_setting("JS_BIODALLIANCE")+"/build/worker-all.js")
+assert_dir(get_setting("JS_TWITTER_POST_FETCHER"))
+assert_file(get_setting("JS_TWITTER_POST_FETCHER")+"/js/twitterFetcher_min.js")
diff --git a/wqflask/wqflask/static/new/javascript/biodalliance.js b/wqflask/wqflask/static/new/javascript/biodalliance.js
new file mode 100644
index 00000000..3b9e3b7f
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/biodalliance.js
@@ -0,0 +1,72 @@
+"use strict";
+
+
+var BD = {};
+BD.browser = null;
+BD.data = {};
+BD.sources = [];
+
+var getChrLen = function(chr) {
+    return js_data[chr * 1];
+};
+
+BD.createBrowser = function(chr, start, end, speciesName, sources) {
+    console.log("creating BD browser");
+    var b = new Browser({
+        chr: chr,
+        viewStart: start,
+        viewEnd: end,
+
+        coordSystem: {
+            speciesName: speciesName
+        },
+
+        sources: sources,
+
+        maxHeight: 1400,
+        setDocumentTitle: false,
+        prefix: '/dalliance/',
+        workerPrefix: 'build/',
+        noPersist: true,
+        pageName: 'bd_container'
+    });
+
+    console.log("created BD browser");
+    return b;
+};
+
+BD.showButton = function() {
+    $('#open_bd').show();
+    $('#close_bd').hide();
+};
+
+BD.hideButton = function() {
+    $('#close_bd').show();
+    $('#open_bd').hide();
+};
+
+
+BD.putData = function(data) {
+    for (var key in data) {
+        BD.data[key] = data[key];
+    }
+};
+
+BD.putSource = function(source) {
+    BD.sources.push(source);
+};
+
+BD.openBrowser = function() {
+    console.log("opening browser");
+    if (!BD.browser) {
+        BD.browser = BD.createBrowser(BD.data.chr,
+                                      0,
+                                      BD.data.length * 1000000,
+                                      BD.data.species,
+                                      BD.sources);
+    } else {
+        BD.browser.setLocation(BD.data.chr, 0, BD.data.length * 1000000);
+    }
+
+    BD.browser.maxViewWidth = BD.data.length * 1000000;
+};
diff --git a/wqflask/wqflask/static/new/javascript/chr_lod_chart.coffee b/wqflask/wqflask/static/new/javascript/chr_lod_chart.coffee
index e00694be..8a5a3569 100644
--- a/wqflask/wqflask/static/new/javascript/chr_lod_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/chr_lod_chart.coffee
@@ -5,7 +5,7 @@ class Chr_Lod_Chart
         @qtl_results = js_data.qtl_results

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

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

-        

+

         @get_max_chr()

 

         @filter_qtl_results()

@@ -21,16 +21,16 @@ class Chr_Lod_Chart
         console.log("@x_coords: ", @x_coords)

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

         console.timeEnd('Create coordinates')

-        

+

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

         @x_buffer = @plot_width/30

         @y_buffer = @plot_height/20

-        

+

         @x_max = d3.max(@x_coords)

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

-    

+

         @y_threshold = @get_lod_threshold()

-    

+

         @svg = @create_svg()

 

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

@@ -43,14 +43,14 @@ class Chr_Lod_Chart
         console.time('Create graph')

         @create_graph()

         console.timeEnd('Create graph')

-       

+

     get_max_chr: () ->

         @max_chr = 0

         for key of js_data.chromosomes

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

             if parseInt(key) > @max_chr

                 @max_chr = parseInt(key)

-        

+

     filter_qtl_results: () ->

         @these_results = []

         this_chr = 100

@@ -59,8 +59,8 @@ class Chr_Lod_Chart
                 this_chr = @max_chr

             else

                 this_chr = result.chr

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

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

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

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

             if this_chr > parseInt(@chr[0])

                 break

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

@@ -72,7 +72,7 @@ class Chr_Lod_Chart
             if result.lod_score > 1

                 high_qtl_count += 1

         console.log("high_qtl_count:", high_qtl_count)

-        

+

         #if high_qtl_count > 10000

         @y_axis_filter = 2

         #else if high_qtl_count > 1000

@@ -85,7 +85,7 @@ class Chr_Lod_Chart
             @x_coords.push(parseFloat(result.Mb))

             @y_coords.push(result.lod_score)

             @marker_names.push(result.name)

-            

+

     create_svg: () ->

         svg = d3.select("#topchart")

             .append("svg")

@@ -102,7 +102,7 @@ class Chr_Lod_Chart
         @y_scale = d3.scale.linear()

             .domain([0, @y_max])

             .range([@plot_height, @y_buffer])

-            

+

     get_lod_threshold: () ->

         if @y_max/2 > 2

             return @y_max/2

@@ -125,7 +125,7 @@ class Chr_Lod_Chart
                          [@y_buffer, @plot_height, @plot_width, @plot_width],

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

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

-            

+

         @svg.selectAll("line")

             .data(border_coords)

             .enter()

@@ -141,7 +141,7 @@ class Chr_Lod_Chart
             )

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

                 return d[3]

-            )             

+            )

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

 

     add_x_axis: () ->

@@ -166,13 +166,13 @@ class Chr_Lod_Chart
                 .attr("transform", (d) =>

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

                 )

-                

+

     add_y_axis: () ->

         @yAxis = d3.svg.axis()

                 .scale(@y_scale)

                 .orient("left")

                 .ticks(5)

-        

+

         @svg.append("g")

             .attr("class", "y_axis")

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

@@ -200,7 +200,7 @@ class Chr_Lod_Chart
                             .x( (d) => return @x_scale(d[0]))

                             .y( (d) => return @y_scale(d[1]))

                             .interpolate("linear")

-                            

+

         line_graph = @svg.append("path")

                         .attr("d", line_function(@plot_coordinates))

                         .attr("stroke", "blue")

@@ -273,6 +273,9 @@ class Chr_Lod_Chart
         $("#return_to_full_view").hide()

         $('#topchart').remove()

         $('#chart_container').append('<div class="qtlcharts" id="topchart"></div>')

+        BD.hideButton()

+        $('#close_bd').hide();

+        $('#bd_container').hide()

         create_lod_chart()

 

     show_marker_in_table: (marker_info) ->

diff --git a/wqflask/wqflask/static/new/javascript/chr_lod_chart.js b/wqflask/wqflask/static/new/javascript/chr_lod_chart.js
index c6cbd01b..bae4565d 100644
--- a/wqflask/wqflask/static/new/javascript/chr_lod_chart.js
+++ b/wqflask/wqflask/static/new/javascript/chr_lod_chart.js
@@ -1,13 +1,12 @@
-// Generated by CoffeeScript 1.9.2
+// Generated by CoffeeScript 1.10.0
 var Chr_Lod_Chart;
 
 Chr_Lod_Chart = (function() {
-  function Chr_Lod_Chart(plot_height, plot_width, chr, manhattanPlot, mappingScale) {
+  function Chr_Lod_Chart(plot_height, plot_width, chr, manhattanPlot) {
     this.plot_height = plot_height;
     this.plot_width = plot_width;
     this.chr = chr;
     this.manhattanPlot = manhattanPlot;
-    this.mappingScale = mappingScale;
     this.qtl_results = js_data.qtl_results;
     console.log("qtl_results are:", this.qtl_results);
     console.log("chr is:", this.chr);
@@ -95,18 +94,11 @@ Chr_Lod_Chart = (function() {
   Chr_Lod_Chart.prototype.create_coordinates = function() {
     var i, len, ref, result, results;
     ref = this.these_results;
-    console.log("THESE_RESULTS:", ref)
     results = [];
     for (i = 0, len = ref.length; i < len; i++) {
       result = ref[i];
       this.x_coords.push(parseFloat(result.Mb));
-      if (js_data.result_score_type == "LOD") {
-        this.y_coords.push(result.lod_score);
-      }
-      else {
-        console.log("LRS VALUE:", result['lrs_value'])
-        this.y_coords.push(result['lrs_value']);
-      }
+      this.y_coords.push(result.lod_score);
       results.push(this.marker_names.push(result.name));
     }
     return results;
@@ -119,19 +111,7 @@ Chr_Lod_Chart = (function() {
   };
 
   Chr_Lod_Chart.prototype.create_scales = function() {
-    if (this.mappingScale == "morgan") {
-        max_pos = 0
-        for (i = 0, len = this.these_results.length; i < len; i++) {
-           marker = this.these_results[i]
-           if (parseFloat(marker['Mb']) > max_pos){
-               max_pos = parseFloat(marker.Mb)
-           }
-        }
-        this.x_scale = d3.scale.linear().domain([0, max_pos]).range([this.x_buffer, this.plot_width]);
-    }
-    else {
-        this.x_scale = d3.scale.linear().domain([0, this.chr[1]]).range([this.x_buffer, this.plot_width]);
-    }
+    this.x_scale = d3.scale.linear().domain([0, this.chr[1]]).range([this.x_buffer, this.plot_width]);
     return this.y_scale = d3.scale.linear().domain([0, this.y_max]).range([this.plot_height, this.y_buffer]);
   };
 
@@ -278,6 +258,9 @@ Chr_Lod_Chart = (function() {
     $("#return_to_full_view").hide();
     $('#topchart').remove();
     $('#chart_container').append('<div class="qtlcharts" id="topchart"></div>');
+    BD.hideButton();
+    $('#close_bd').hide();
+    $('#bd_container').hide();
     return create_lod_chart();
   };
 
diff --git a/wqflask/wqflask/static/new/javascript/create_lodchart.coffee b/wqflask/wqflask/static/new/javascript/create_lodchart.coffee
index 88003f4e..f6dfd7a3 100644
--- a/wqflask/wqflask/static/new/javascript/create_lodchart.coffee
+++ b/wqflask/wqflask/static/new/javascript/create_lodchart.coffee
@@ -9,9 +9,9 @@ create_lod_chart = ->
         additive = js_data.additive
     else
         additive = false
-    
+
     console.log("js_data:", js_data)
-    
+
     # simplest use
     #d3.json "data.json", (data) ->
     mychart = lodchart().lodvarname("lod.hk")
@@ -21,13 +21,13 @@ create_lod_chart = ->
                         .ylab(js_data.result_score_type + " score")
                         .manhattanPlot(js_data.manhattan_plot)
                         #.additive(additive)
-                        
+
     data = js_data.json_data
-    
+
     d3.select("div#topchart")
       .datum(data)
       .call(mychart)
-    
+
     # grab chromosome rectangles; color pink on hover
     chrrect = mychart.chrSelect()
     chrrect.on "mouseover", ->
@@ -36,7 +36,7 @@ create_lod_chart = ->
                 d3.select(this).attr("fill", ->
                       return "#F1F1F9"  if i % 2
                       "#FBFBFF")
-    
+
     # animate points at markers on click
     mychart.markerSelect()
               .on "click", (d) ->
@@ -44,7 +44,3 @@ create_lod_chart = ->
                     d3.select(this)
                       .transition().duration(500).attr("r", r*3)
                       .transition().duration(500).attr("r", r)
-
-$ ->
-    root.create_lod_chart = create_lod_chart
-
diff --git a/wqflask/wqflask/static/new/javascript/create_lodchart.js b/wqflask/wqflask/static/new/javascript/create_lodchart.js
index 778eed3a..d2c531f9 100644
--- a/wqflask/wqflask/static/new/javascript/create_lodchart.js
+++ b/wqflask/wqflask/static/new/javascript/create_lodchart.js
@@ -1,4 +1,5 @@
-//var create_lod_chart;
+// Generated by CoffeeScript 1.10.0
+var create_lod_chart;
 
 create_lod_chart = function() {
   var additive, chrrect, data, h, halfh, margin, mychart, totalh, totalw, w;
@@ -40,11 +41,3 @@ create_lod_chart = function() {
     return d3.select(this).transition().duration(500).attr("r", r * 3).transition().duration(500).attr("r", r);
   });
 };
-
-create_lod_chart()
-
-/*
-$(function() {
-  return root.create_lod_chart = create_lod_chart;
-});
-*/
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/lod_chart.coffee b/wqflask/wqflask/static/new/javascript/lod_chart.coffee
index 55ffdce0..a65df84f 100644
--- a/wqflask/wqflask/static/new/javascript/lod_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/lod_chart.coffee
@@ -123,6 +123,8 @@ lodchart = () ->
                    .on("click", (d) ->
                       console.log("d is:", d)
                       redraw_plot(d)
+                      BD.putData({chr: d[0], length: d[1]});
+                      BD.showButton()
                     )   
   
         # x-axis labels
diff --git a/wqflask/wqflask/static/new/javascript/lod_chart.js b/wqflask/wqflask/static/new/javascript/lod_chart.js
index 014bf59b..f1df6bd8 100644
--- a/wqflask/wqflask/static/new/javascript/lod_chart.js
+++ b/wqflask/wqflask/static/new/javascript/lod_chart.js
@@ -1,8 +1,8 @@
-// Generated by CoffeeScript 1.9.2
+// Generated by CoffeeScript 1.10.0
 var lodchart;
 
 lodchart = function() {
-  var additive, additive_ylab, additive_ylim, additive_yscale, additive_yticks, additivelinecolor, axispos, chart, chrGap, chrSelect, darkrect, height, lightrect, linewidth, lodcurve, lodlinecolor, lodvarname, manhattanPlot, mappingScale, margin, markerSelect, nyticks, pad4heatmap, pointcolor, pointsAtMarkers, pointsize, pointstroke, rotate_ylab, significantcolor, suggestivecolor, title, titlepos, width, xlab, xscale, ylab, ylim, yscale, yticks;
+  var additive, additive_ylab, additive_ylim, additive_yscale, additive_yticks, additivelinecolor, axispos, chart, chrGap, chrSelect, darkrect, height, lightrect, linewidth, lodcurve, lodlinecolor, lodvarname, manhattanPlot, margin, markerSelect, nyticks, pad4heatmap, pointcolor, pointsAtMarkers, pointsize, pointstroke, rotate_ylab, significantcolor, suggestivecolor, title, titlepos, width, xlab, xscale, ylab, ylim, yscale, yticks;
   width = 800;
   height = 500;
   margin = {
@@ -20,6 +20,7 @@ lodchart = function() {
   };
   titlepos = 20;
   manhattanPlot = false;
+  additive = false;
   ylim = null;
   additive_ylim = null;
   nyticks = 5;
@@ -29,8 +30,7 @@ lodchart = function() {
   darkrect = "#F1F1F9";
   lightrect = "#FBFBFF";
   lodlinecolor = "darkslateblue";
-  additivelinecolor_plus = "red";
-  additivelinecolor_negative = "green";
+  additivelinecolor = "red";
   linewidth = 2;
   suggestivecolor = "gainsboro";
   significantcolor = "#EBC7C7";
@@ -70,15 +70,14 @@ lodchart = function() {
         return results;
       })();
       ylim = ylim != null ? ylim : [0, d3.max(data[lodvarname])];
-
-      if ('additive' in data) {
+      if (additive) {
         data['additive'] = (function() {
           var j, len, ref, results;
           ref = data['additive'];
           results = [];
           for (j = 0, len = ref.length; j < len; j++) {
             x = ref[j];
-            results.push(x);
+            results.push(Math.abs(x));
           }
           return results;
         })();
@@ -92,12 +91,12 @@ lodchart = function() {
       g.append("rect").attr("x", margin.left).attr("y", margin.top).attr("height", height).attr("width", width).attr("fill", darkrect).attr("stroke", "none");
       yscale.domain(ylim).range([height + margin.top, margin.top + margin.inner]);
       yticks = yticks != null ? yticks : yscale.ticks(nyticks);
-      if ('additive' in data) {
+      if (additive) {
         additive_yscale.domain(additive_ylim).range([height + margin.top, margin.top + margin.inner + height / 2]);
         additive_yticks = additive_yticks != null ? additive_yticks : additive_yscale.ticks(nyticks);
       }
       reorgLodData(data, lodvarname);
-      data = chrscales(data, width, chrGap, margin.left, pad4heatmap, mappingScale);
+      data = chrscales(data, width, chrGap, margin.left, pad4heatmap);
       xscale = data.xscale;
       chrSelect = g.append("g").attr("class", "chrRect").selectAll("empty").data(data.chrnames).enter().append("rect").attr("id", function(d) {
         return "chrrect" + d[0];
@@ -118,7 +117,12 @@ lodchart = function() {
         return lightrect;
       }).attr("stroke", "none").on("click", function(d) {
         console.log("d is:", d);
-        return redraw_plot(d);
+        redraw_plot(d);
+        BD.putData({
+          chr: d[0],
+          length: d[1]
+        });
+        return BD.showButton();
       });
       xaxis = g.append("g").attr("class", "x axis");
       xaxis.selectAll("empty").data(data.chrnames).enter().append("text").text(function(d) {
@@ -133,7 +137,7 @@ lodchart = function() {
         var chr_plot;
         $('#topchart').remove();
         $('#chart_container').append('<div class="qtlcharts" id="topchart"></div>');
-        return chr_plot = new Chr_Lod_Chart(600, 1200, chr_ob, manhattanPlot, mappingScale);
+        return chr_plot = new Chr_Lod_Chart(600, 1200, chr_ob, manhattanPlot);
       };
       rotate_ylab = rotate_ylab != null ? rotate_ylab : ylab.length > 1;
       yaxis = g.append("g").attr("class", "y axis");
@@ -148,7 +152,7 @@ lodchart = function() {
         return formatAxis(yticks)(d);
       });
       yaxis.append("text").attr("class", "title").attr("y", margin.top + height / 2).attr("x", margin.left - axispos.ytitle).text(ylab).attr("transform", rotate_ylab ? "rotate(270," + (margin.left - axispos.ytitle) + "," + (margin.top + height / 2) + ")" : "").attr("text-anchor", "middle").attr("fill", "slateblue");
-      if ('additive' in data) {
+      if (additive) {
         rotate_additive_ylab = rotate_additive_ylab != null ? rotate_additive_ylab : additive_ylab.length > 1;
         additive_yaxis = g.append("g").attr("class", "y axis");
         additive_yaxis.selectAll("empty").data(additive_yticks).enter().append("line").attr("y1", function(d) {
@@ -187,19 +191,13 @@ lodchart = function() {
             return yscale(data.lodByChr[chr][i][lodcolumn]);
           });
         };
-        if ('additive' in data) {
+        if (additive) {
           additivecurve = function(chr, lodcolumn) {
-            if (data.additiveByChr[chr][0] < 0) {
-              pos_neg = "negative"
-            }
-            else {
-              pos_neg = "positive"
-            }
-            return [pos_neg, d3.svg.line().x(function(d) {
+            return d3.svg.line().x(function(d) {
               return xscale[chr](d);
             }).y(function(d, i) {
-              return additive_yscale(Math.abs(data.additiveByChr[chr][i]));
-            })];
+              return additive_yscale(data.additiveByChr[chr][i][lodcolumn]);
+            });
           };
         }
         curves = g.append("g").attr("id", "curves");
@@ -210,17 +208,12 @@ lodchart = function() {
             curves.append("path").datum(data.posByChr[chr[0]]).attr("d", lodcurve(chr[0], lodvarnum)).attr("stroke", lodlinecolor).attr("fill", "none").attr("stroke-width", linewidth).style("pointer-events", "none");
           }
         }
-        if ('additive' in data) {
+        if (additive) {
           ref1 = data.chrnames;
           for (k = 0, len1 = ref1.length; k < len1; k++) {
             chr = ref1[k];
             if (chr.indexOf(data['chr'])) {
-              if (additivecurve(chr[0], lodvarnum)[0] == "negative") {
-                curves.append("path").datum(data.posByChr[chr[0]]).attr("d", additivecurve(chr[0], lodvarnum)[1]).attr("stroke", additivelinecolor_negative).attr("fill", "none").attr("stroke-width", 1).style("pointer-events", "none");
-              }
-              else {
-                curves.append("path").datum(data.posByChr[chr[0]]).attr("d", additivecurve(chr[0], lodvarnum)[1]).attr("stroke", additivelinecolor_plus).attr("fill", "none").attr("stroke-width", 1).style("pointer-events", "none");
-              }
+              curves.append("path").datum(data.posByChr[chr[0]]).attr("d", additivecurve(chr[0], lodvarnum)).attr("stroke", additivelinecolor).attr("fill", "none").attr("stroke-width", 1).style("pointer-events", "none");
             }
           }
         }
@@ -305,13 +298,6 @@ lodchart = function() {
     manhattanPlot = value;
     return chart;
   };
-  chart.mappingScale = function(value) {
-    if (!arguments.length) {
-      return mappingScale;
-    }
-    mappingScale = value;
-    return chart;
-  };
   chart.ylim = function(value) {
     if (!arguments.length) {
       return ylim;
@@ -449,6 +435,9 @@ lodchart = function() {
   chart.yscale = function() {
     return yscale;
   };
+  chart.additive = function() {
+    return additive;
+  };
   chart.additive_yscale = function() {
     return additive_yscale;
   };
@@ -470,4 +459,4 @@ lodchart = function() {
     return chrSelect;
   };
   return chart;
-};
\ No newline at end of file
+};
diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/marker_regression_gn1.html
index 6d3f9326..31b8c595 100644
--- a/wqflask/wqflask/templates/marker_regression_gn1.html
+++ b/wqflask/wqflask/templates/marker_regression_gn1.html
@@ -32,7 +32,7 @@
         <input type="hidden" name="mapmethod_rqtl_geno" value="{{ mapmethod_rqtl_geno }}">
         <input type="hidden" name="mapmodel_rqtl_geno" value="{{ mapmodel_rqtl_geno }}">
         <input type="hidden" name="pair_scan" value="{{ pair_scan }}">
-        
+
         <div class="container">
           <div class="col-xs-5">
               <h2>Map Viewer: Whole Genome</h2><br>
@@ -81,7 +81,7 @@
                 <tr>
                   <td></td>
                   <td style="padding: 5px;">
-                    <input type="text" name="lrsMax" value="{{ '%0.1f' | format(lrsMax|float) }}" size="3"> <span style="font-size: 12px;">units on the y-axis (0 for default)</span>   
+                    <input type="text" name="lrsMax" value="{{ '%0.1f' | format(lrsMax|float) }}" size="3"> <span style="font-size: 12px;">units on the y-axis (0 for default)</span>
                   </td>
                 </tr>
                 <tr>
@@ -94,14 +94,14 @@
             </div>
             <div class="col-xs-4" style="padding: 0px;">
                   {% if (mapping_method == "reaper" or mapping_method == "rqtl_geno") and nperm > 0 %}
-                  <input type="checkbox" name="permCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if permChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Permutation Test 
+                  <input type="checkbox" name="permCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if permChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Permutation Test
                     <a href="http://genenetwork.org/glossary.html#Permutation" target="_blank">
                       <sup style="color:#f00"> ?</sup>
                     </a>
                   <br>
                   {% endif %}
                   {% if mapping_method == "reaper" and nboot > 0 %}
-                  <input type="checkbox" name="bootCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if bootChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Bootstrap Test 
+                  <input type="checkbox" name="bootCheck" class="checkbox" style="display: inline; margin-top: 0px;" {% if bootChecked|upper == "ON" %}value="ON" checked{% endif %}> <span style="font-size: 12px;">Bootstrap Test
                     <a href="http://genenetwork.org/glossary.html#bootstrap" target="_blank">
                       <sup style="color:#f00"> ?</sup>
                     </a>
@@ -131,7 +131,7 @@
             </div>
           </div>
         </div>
- 
+
         <div class="tabbable" style="margin: 10px;">
           <ul class="nav nav-tabs">
             <li id="gn1_map_tab">
@@ -163,8 +163,23 @@
             </div>
             {% if mapping_method != "gemma" %}
             <div class="tab-pane {% if mapping_method == "gemma" %}active{% endif %}" id="vector_map">
-              <div id="chart_container">
-                <div class="qtlcharts" id="topchart"></div>
+                <div id="chart_container">
+                    <ul class="nav nav-tabs">
+                        <li id="return_to_full_view" class="btn btn-default buttons-html5" style="display:none">
+                            Return to full view
+                        </li>
+                        <li id="open_bd" class="btn btn-default buttons-html5" style="display:none">
+                            Open BioDalliance view
+                        </li>
+                        <li id="close_bd" class="btn btn-default buttons-html5" style="display:none">
+                            Return to vector map
+                        </li>
+                    </ul>
+
+                    <div class="qtlcharts" id="topchart"></div>
+
+                    <div id="bd_container" class="qtlcharts">
+                    </div>
               </div>
             </div>
             {% endif %}
@@ -265,7 +280,37 @@
 
 {% endblock %}
 
-{% block js %}  
+{% block js %}
+
+    <script>
+      /* This section checks for paths to JS libraries by
+         checking the headers */
+      list = [
+      /* check for static path */
+      "/static/new/javascript/biodalliance.js",
+      "/static/new/js_external/underscore-min.js",
+      /* check for dalliance JS (see ./etc/default_settings.py) */
+      "/dalliance/build/dalliance-all.js",
+      /* D3 path (FIXME) */
+      "http://d3js.org/d3.v3.min.js",
+      /* datatables path (FIXME) */
+      "https://cdn.datatables.net/buttons/1.0.0/js/dataTables.buttons.min.js"
+      ];
+      for (var i = 0; i < list.length; i++) {
+        url = list[i];
+        $.ajax({
+          type: 'HEAD',
+          url: url,
+          success: function() {
+            // page exists
+          },
+          error: function() {
+            // page does not exist
+            console.log("Failed to load "+this.url);
+            alert("Failed to load Javascript for "+this.url);
+          }
+      })};
+    </script>
 
     <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
     <script type="text/javascript" src="/static/new/js_external/underscore-min.js"></script>
@@ -277,19 +322,19 @@
     <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.scientific.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script>
 
-    <script>
-        js_data = {{ js_data | safe }}
-    </script>
 
     {% if mapping_method != "gemma" %}
     <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> 
+    <script language="javascript" type="text/javascript" src="/static/new/javascript/chr_lod_chart.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/javascript/lod_chart.js"></script>
     <script language="javascript" type="text/javascript" src="/static/new/javascript/create_lodchart.js"></script>
+
+    <script language="javascript" type="text/javascript" src="/dalliance/build/dalliance-all.js"></script>
+    <script language="javascript" type="text/javascript" src="/static/new/javascript/biodalliance.js"></script>
     {% endif %}
 
-    <script type="text/javascript" charset="utf-8">
-        $(document).ready( function () {
+    <script>
+     createTable = function() {
             console.time("Creating table");
             $('#qtl_results').DataTable( {
                 {% if mapping_method != "reaper" %}
@@ -353,15 +398,145 @@
                 "scrollCollapse": false,
                 "paging": false
             } );
+     };
+
+     filename = "{{json_filename}}";
+     js_data = null;
+     $.ajax("/generated_text/{{json_filename}}",
+            {success:
+                     function(data) {
+                         js_data = data;
+                         create_lod_chart();
+                         createTable();
+                     }
+            });
+
+     BD.putSource({name: 'Genome',
+                   twoBitURI:  'http://www.biodalliance.org/datasets/GRCm38/mm10.2bit',
+                   desc: 'Mouse reference genome build GRCm38',
+                   tier_type: 'sequence',
+                   provides_entrypoints: true
+     });
+     BD.putSource({name: 'Genotype',
+                   controlURI: "{{gn_server_url}}/api_pre1/genotype/mouse/BXD.json",
+                   URIBase:    "{{gn_server_url}}/api_pre1/genotype/mouse/",
+                   tier_type:  'rqtl-genotype',
+                   vOffset: 8,
+                   pinned: true,
+                   transposed: true,
+                   hideSubpixelGlyphs: true,
+                   style: [
+                       { type: "default",
+                         method: "U",
+                         style: { glyph: "BOX",
+                                  LINE: "0.5",
+                                  FGCOLOR: "black",
+                                  BGCOLOR: "white",
+                                  BGITEM: "true",
+                                  HEIGHT: "2",
+                                  BUMP: "true",
+                         }},
+                       { type: "default",
+                         method: "B",
+                         style: { glyph: "BOX",
+                                  LINE: "0.5",
+                                  FGCOLOR: "blue",
+                                  BGCOLOR: "blue",
+                                  BGITEM: "true",
+                                  HEIGHT: "2",
+                                  BUMP: "true",
+                         }},
+                       { type: "default",
+                         method: "H",
+                         style: { glyph: "BOX",
+                                  LINE: "0.5",
+                                  FGCOLOR: "green",
+                                  BGCOLOR: "green",
+                                  BGITEM: "true",
+                                  HEIGHT: "2",
+                                  BUMP: "true",
+                         }},
+                       { type: "default",
+                         method: "D",
+                         style: { glyph: "BOX",
+                                  LINE: "0.5",
+                                  FGCOLOR: "red",
+                                  BGCOLOR: "red",
+                                  BGITEM: "true",
+                                  HEIGHT: "2",
+                                  BUMP: "true",
+                         }},
+                   ]
+     });
+     BD.putSource({name: 'QTL',
+                   tier_type: 'qtl',
+                   uri: '/generated_text/{{csv_filename}}',
+                   style: [{
+                       type: 'default',
+                       style: {
+                           glyph: "LINEPLOT",
+                           AUTOMAX: "true",
+                           MIN: 0,
+                           MAX: 3,
+                           HEIGHT: 200,
+                           STEPS: 500,
+                           COLOR1: "blue",
+                       }
+                   }],
+     });
+     BD.putSource({name: 'SNP density',
+                   jbURI: "{{gn_server_url}}/api_pre1/snp",
+                   jbQuery: "",
+                   refetchOnZoom: true,
+                   style: [{
+                       type: 'default',
+                       style: {
+                           glyph: "HISTOGRAM",
+                           MIN: 0,
+                           MAX: 5000,
+                           AUTOMAX: "true",
+                           HEIGHT: 60,
+                           STEPS: 100,
+                           COLOR1: "red",
+                           COLOR2: "red",
+                           COLOR3: "red",
+                           AXISCENTER: "true",
+                       }
+                   }]
+     });
+    </script>
+
+    <script type="text/javascript" charset="utf-8">
+        $(document).ready( function () {
+            BD.putData({species: "{{ dataset.group.species }}" });
+
 
             $('#vector_map_tab').click(function(){
                 $('div#gn1_map_options').hide();
             });
 
             $('#gn1_map_tab').click(function(){
-                $('div#gn1_map_options').show();
+                $('#gn1_map_options').show();
+                $('div#bd_container').hide();
             });
 
+            $('#close_bd').click(function() {
+                $('#open_bd').show();
+                $('#close_bd').hide();
+
+                $('#bd_container').hide();
+                $('#topchart').show();
+            });
+
+            $('#open_bd').click(function() {
+                $('#close_bd').show();
+                $('#open_bd').hide()
+
+                $('#topchart').hide();
+                $('#bd_container').show();
+
+                BD.openBrowser();
+            })
         });
 
         chrView = function(this_chr, chr_mb_list) {
@@ -380,9 +555,9 @@
             return $('#marker_regression_form').submit();
         };
 
-        remap = function() { 
+        remap = function() {
             $('input[name=selected_chr]').val($('select[name=chromosomes]').val());
-            return $('#marker_regression_form').submit(); 
+            return $('#marker_regression_form').submit();
         };
 
         export_perm_data = function() {
@@ -398,4 +573,3 @@
     </script>
 
 {% endblock %}
-
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index ab6c433d..c3b91c6e 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -21,6 +21,7 @@ import uuid
 
 import simplejson as json
 import yaml
+import csv
 
 #Switching from Redis to StrictRedis; might cause some issues
 import redis
@@ -52,12 +53,13 @@ from wqflask.wgcna import wgcna_analysis
 from wqflask.ctl import ctl_analysis
 #from wqflask.trait_submission import submit_trait
 
+from utility import webqtlUtil
 from utility import temp_data
 from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION
 from utility.helper_functions import get_species_groups
 
 from base import webqtlFormData
-from base.webqtlConfig import GENERATED_IMAGE_DIR
+from base.webqtlConfig import GENERATED_IMAGE_DIR, GENERATED_TEXT_DIR
 from utility.benchmark import Bench
 
 from pprint import pformat as pf
@@ -147,10 +149,16 @@ def tmp_page(img_path):
                             img_base64 = bytesarray )
 
 @app.route("/twitter/<path:filename>")
-def bd_files(filename):
-    bd_path = app.config['TWITTER_POST_FETCHER_JS_PATH']
+def twitter_js(filename):
+    bd_path = app.config['JS_TWITTER_POST_FETCHER']
+    return send_from_directory(bd_path, filename)
+
+@app.route("/dalliance/<path:filename>")
+def biodalliance_js(filename):
+    bd_path = app.config['JS_BIODALLIANCE']
     return send_from_directory(bd_path, filename)
 
+
 #@app.route("/data_sharing")
 #def data_sharing_page():
 #    logger.info("In data_sharing")
@@ -235,6 +243,10 @@ def docedit():
 def generated_file(filename):
     return send_from_directory(GENERATED_IMAGE_DIR,filename)
 
+@app.route('/generated_text/<filename>')
+def generated_text(filename):
+    return send_from_directory(GENERATED_TEXT_DIR, filename)
+
 @app.route("/help")
 def help():
     doc = docs.Docs("help")
@@ -575,10 +587,27 @@ def marker_regression_page():
         with Bench("Total time in MarkerRegression"):
             template_vars = marker_regression.MarkerRegression(start_vars, temp_uuid)
 
+
+        qtl_results = template_vars.js_data['qtl_results']
+
         template_vars.js_data = json.dumps(template_vars.js_data,
                                            default=json_default_handler,
                                            indent="   ")
 
+
+        json_filename = webqtlUtil.genRandStr("") + ".json"
+        with open(GENERATED_TEXT_DIR + "/" + json_filename, "wb") as json_file:
+            json_file.write(template_vars.js_data)
+
+        csv_filename = webqtlUtil.genRandStr("") + ".csv"
+        with open(GENERATED_TEXT_DIR + "/" + csv_filename, "wb") as csv_file:
+            writer = csv.writer(csv_file)
+            writer.writerow(("Locus", "Chr", "Mb", "LOD"))
+            for (row) in qtl_results:
+                score = row["lod_score"] if "lod_score" in row else row["lrs_value"]
+                writer.writerow((row["name"], row["chr"], row["Mb"], score))
+
+
         result = template_vars.__dict__
 
         if result['pair_scan']:
@@ -598,6 +627,9 @@ def marker_regression_page():
             #    logger.info("  ---**--- {}: {}".format(type(template_vars.__dict__[item]), item))
 
             gn1_template_vars = marker_regression_gn1.MarkerRegression(result).__dict__
+            gn1_template_vars['json_filename'] = json_filename;
+            gn1_template_vars['csv_filename'] = csv_filename;
+            gn1_template_vars['gn_server_url'] = GN_SERVER_URL;
 
             pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL)
             logger.info("pickled result length:", len(pickled_result))
@@ -607,22 +639,6 @@ def marker_regression_page():
             with Bench("Rendering template"):
                 rendered_template = render_template("marker_regression_gn1.html", **gn1_template_vars)
 
-    # with Bench("Rendering template"):
-        # if result['pair_scan'] == True:
-            # img_path = result['pair_scan_filename']
-            # logger.info("img_path:", img_path)
-            # initial_start_vars = request.form
-            # logger.info("initial_start_vars:", initial_start_vars)
-            # imgfile = open(TEMPDIR + '/' + img_path, 'rb')
-            # imgdata = imgfile.read()
-            # imgB64 = imgdata.encode("base64")
-            # bytesarray = array.array('B', imgB64)
-            # result['pair_scan_array'] = bytesarray
-            # rendered_template = render_template("pair_scan_results.html", **result)
-        # else:
-            # rendered_template = render_template("marker_regression.html", **result)
-            # rendered_template = render_template("marker_regression_gn1.html", **gn1_template_vars)
-
     return rendered_template