From 4e6c8eba35a5ecd9e6b5b1c5faa98021656acb9d Mon Sep 17 00:00:00 2001
From: zsloan
Date: Mon, 12 Aug 2019 16:34:05 -0500
Subject: Fixed some things to update the genome browser and get it running
correctly
Fixed issue where trait page for genotype traits didn't work
Removed bad y axis title on probability plot
---
.../marker_regression/display_mapping_results.py | 9 +
wqflask/wqflask/marker_regression/run_mapping.py | 49 +-
wqflask/wqflask/show_trait/show_trait.py | 4 +-
.../static/new/javascript/init_genome_browser.js | 168 +-
.../new/javascript/plotly_probability_plot.js | 1 -
.../css/purescript-genetics-browser.css | 1 +
.../css/purescript_genetics_browser_v01.css | 1 -
.../js/purescript-genetics-browser.js | 63016 +++++++++++++++++++
.../js/purescript-genetics-browser_v01.js | 659 -
wqflask/wqflask/templates/mapping_results.html | 10 +-
wqflask/wqflask/views.py | 4 +-
11 files changed, 63166 insertions(+), 756 deletions(-)
create mode 100644 wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript-genetics-browser.css
delete mode 100644 wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript_genetics_browser_v01.css
create mode 100644 wqflask/wqflask/static/packages/purescript_genome_browser/js/purescript-genetics-browser.js
delete mode 100644 wqflask/wqflask/static/packages/purescript_genome_browser/js/purescript-genetics-browser_v01.js
diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py
index ea1ca5ed..b1e9dad4 100644
--- a/wqflask/wqflask/marker_regression/display_mapping_results.py
+++ b/wqflask/wqflask/marker_regression/display_mapping_results.py
@@ -31,6 +31,7 @@ import piddle as pid
import sys,os
import cPickle
import httplib
+import json
from flask import Flask, g
@@ -1696,6 +1697,14 @@ class DisplayMappingResults(object):
else:
LRS_LOD_Max = self.lrsMax
+ #ZS: Needed to pass to genome browser
+ js_data = json.loads(self.js_data)
+ if self.LRS_LOD == "LRS":
+ js_data['max_score'] = LRS_LOD_Max/4.16
+ else:
+ js_data['max_score'] = LRS_LOD_Max
+ self.js_data = json.dumps(js_data)
+
if LRS_LOD_Max > 100:
LRSScale = 20.0
elif LRS_LOD_Max > 20:
diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py
index 7f6bb0a5..11ad7aa4 100644
--- a/wqflask/wqflask/marker_regression/run_mapping.py
+++ b/wqflask/wqflask/marker_regression/run_mapping.py
@@ -7,6 +7,7 @@ from pprint import pformat as pf
import string
import math
+from decimal import Decimal
import random
import sys
import datetime
@@ -314,30 +315,41 @@ class RunMapping(object):
else:
self.qtl_results = []
self.qtl_results_for_browser = []
+ self.annotations_for_browser = []
highest_chr = 1 #This is needed in order to convert the highest chr to X/Y
for marker in results:
browser_marker = dict(
chr = str(marker['chr']),
rs = marker['name'],
- ps = marker['Mb']*1000000
+ ps = marker['Mb']*1000000,
+ url = "/show_trait?trait_id=" + marker['name'] + "&dataset=" + self.dataset.group.name + "Geno"
)
- if 'p_value' in marker:
- browser_marker['p_wald'] = marker['p_value']
+ annot_marker = dict(
+ name = str(marker['name']),
+ chr = str(marker['chr']),
+ rs = marker['name'],
+ pos = marker['Mb']*1000000,
+ url = "/show_trait?trait_id=" + marker['name'] + "&dataset=" + self.dataset.group.name + "Geno"
+ )
+ #if 'p_value' in marker:
+ # logger.debug("P EXISTS:", marker['p_value'])
+ #else:
+ if 'lrs_value' in marker and marker['lrs_value'] > 0:
+ browser_marker['p_wald'] = 10**-(marker['lrs_value']/4.61)
+ elif 'lod_score' in marker and marker['lod_score'] > 0:
+ browser_marker['p_wald'] = 10**-(marker['lod_score'])
else:
- if 'lrs_value' in marker and marker['lrs_value'] > 0:
- browser_marker['p_wald'] = -math.log10(marker['lrs_value']/4.16)
- elif 'lod_score' in marker and marker['lod_score'] > 0:
- browser_marker['p_wald'] = -math.log10(marker['lod_score'])
- else:
- browser_marker['p_wald'] = 0
+ browser_marker['p_wald'] = 0
+
self.qtl_results_for_browser.append(browser_marker)
+ self.annotations_for_browser.append(annot_marker)
if marker['chr'] > 0 or marker['chr'] == "X" or marker['chr'] == "X/Y":
if marker['chr'] > highest_chr or marker['chr'] == "X" or marker['chr'] == "X/Y":
highest_chr = marker['chr']
if ('lod_score' in marker.keys()) or ('lrs_value' in marker.keys()):
self.qtl_results.append(marker)
- browser_files = write_input_for_browser(self.dataset, self.qtl_results_for_browser)
+ browser_files = write_input_for_browser(self.dataset, self.qtl_results_for_browser, self.annotations_for_browser)
with Bench("Exporting Results"):
export_mapping_results(self.dataset, self.this_trait, self.qtl_results, self.mapping_results_path, self.mapping_scale, self.score_type)
@@ -350,6 +362,11 @@ class RunMapping(object):
self.trimmed_markers = trim_markers_for_table(results)
if self.mapping_method != "gemma":
+ if self.score_type == "LRS":
+ significant_for_browser = self.significant / 4.16
+ else:
+ significant_for_browser = self.significant
+
self.js_data = dict(
#result_score_type = self.score_type,
#this_trait = self.this_trait.name,
@@ -361,7 +378,8 @@ class RunMapping(object):
#qtl_results = self.qtl_results,
num_perm = self.num_perm,
perm_results = self.perm_output,
- browser_files = browser_files
+ browser_files = browser_files,
+ significant = significant_for_browser
)
else:
self.js_data = dict(
@@ -406,6 +424,7 @@ class RunMapping(object):
def export_mapping_results(dataset, trait, markers, results_path, mapping_scale, score_type):
with open(results_path, "w+") as output_file:
+ output_file.write("Time/Date: " + datetime.datetime.now().strftime("%x / %X") + "\n")
output_file.write("Population: " + dataset.group.species.title() + " " + dataset.group.name + "\n")
output_file.write("Data Set: " + dataset.fullname + "\n")
if dataset.type == "ProbeSet":
@@ -413,6 +432,8 @@ def export_mapping_results(dataset, trait, markers, results_path, mapping_scale,
output_file.write("Location: " + str(trait.chr) + " @ " + str(trait.mb) + " Mb\n")
output_file.write("\n")
output_file.write("Name,Chr,")
+ if score_type.lower() == "-log(p)":
+ score_type = "'-log(p)"
if mapping_scale == "physic":
output_file.write("Mb," + score_type)
else:
@@ -491,7 +512,7 @@ def trim_markers_for_table(markers):
else:
return sorted_markers
-def write_input_for_browser(this_dataset, markers):
+def write_input_for_browser(this_dataset, gwas_results, annotations):
file_base = this_dataset.group.name + "_" + ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
gwas_filename = file_base + "_GWAS"
annot_filename = file_base + "_ANNOT"
@@ -499,8 +520,8 @@ def write_input_for_browser(this_dataset, markers):
annot_path = "{}/gn2/".format(TEMPDIR) + annot_filename
with open(gwas_path + ".json", "w") as gwas_file, open(annot_path + ".json", "w") as annot_file:
- gwas_file.write(json.dumps(markers))
- annot_file.write(json.dumps([]))
+ gwas_file.write(json.dumps(gwas_results))
+ annot_file.write(json.dumps(annotations))
return [gwas_filename, annot_filename]
#return [gwas_filename, annot_filename]
\ No newline at end of file
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index b0a46b32..02c65d47 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -194,10 +194,10 @@ class ShowTrait(object):
trait_symbol = self.this_trait.symbol
short_description = trait_symbol
- elif self.this_trait.post_publication_abbreviation:
+ elif hasattr(self.this_trait, 'post_publication_abbreviation'):
short_description = self.this_trait.post_publication_abbreviation
- elif self.this_trait.pre_publication_abbreviation:
+ elif hasattr(self.this_trait, 'pre_publication_abbreviation'):
short_description = self.this_trait.pre_publication_abbreviation
# Todo: Add back in the ones we actually need from below, as we discover we need them
diff --git a/wqflask/wqflask/static/new/javascript/init_genome_browser.js b/wqflask/wqflask/static/new/javascript/init_genome_browser.js
index 64a300bc..7dfd6712 100644
--- a/wqflask/wqflask/static/new/javascript/init_genome_browser.js
+++ b/wqflask/wqflask/static/new/javascript/init_genome_browser.js
@@ -1,73 +1,97 @@
-console.log("THE FILES:", js_data.browser_files)
-
-snps_filename = "/browser_input?filename=" + js_data.browser_files[0]
-annot_filename = "/browser_input?filename=" + js_data.browser_files[1]
-
-localUrls =
-{
- snps: snps_filename,
- annotations: null
-};
-
-var vscaleWidth = 90.0;
-var legendWidth = 140.0;
-var score = { min: 0.0, max: 30.0, sig: 4 };
-var gwasPadding = { top: 35.0,
- bottom: 35.0,
- left: vscaleWidth,
- right: legendWidth };
-var gwasHeight = 420.0;
-var genePadding = { top: 10.0,
- bottom: 35.0,
- left: vscaleWidth,
- right: legendWidth };
-var geneHeight = 140.0;
-
-
-var config =
-{ trackHeight: 400.0,
- padding: gwasPadding,
- score: score,
- urls: localUrls,
- tracks: {
- gwas: {
- trackHeight: gwasHeight,
- padding: gwasPadding,
- snps: {
- radius: 3.75,
- lineWidth: 1.0,
- color: { outline: "#FFFFFF",
- fill: "#00008B" },
- pixelOffset: {x: 0.0, y: 0.0}
- },
- annotations: {
- radius: 5.5,
- outline: "#000000",
- snpColor: "#0074D9",
- geneColor: "#FF4136"
- },
- score: score,
- legend: {
- fontSize: 14,
- hPad: 0.2,
- vPad: 0.2
- },
- vscale: {
- color: "#000000",
- hPad: 0.125,
- numSteps: 3,
- fonts: { labelSize: 18, scaleSize: 16 }
- },
- }
- },
- chrs: {
- chrBG1: "#FFFFFF",
- chrBG2: "#DDDDDD",
- chrLabels: { fontSize: 16 },
- },
- initialChrs: { left: "1", right: "19" }
-};
-
-GenomeBrowser.main(config)();
-
+console.log("THE FILES:", js_data.browser_files)
+
+snps_filename = "/browser_input?filename=" + js_data.browser_files[0]
+annot_filename = "/browser_input?filename=" + js_data.browser_files[1]
+
+localUrls =
+{
+ snps: snps_filename,
+ annotations: annot_filename
+};
+
+var coordinateSystem =
+ [
+ { chr: "1", size: "195471971" },
+ { chr: "2", size: "182113224" },
+ { chr: "3", size: "160039680" },
+ { chr: "4", size: "156508116" },
+ { chr: "5", size: "151834684" },
+ { chr: "6", size: "149736546" },
+ { chr: "7", size: "145441459" },
+ { chr: "8", size: "129401213" },
+ { chr: "9", size: "124595110" },
+ { chr: "10", size: "130694993" },
+ { chr: "11", size: "122082543" },
+ { chr: "12", size: "120129022" },
+ { chr: "13", size: "120421639" },
+ { chr: "14", size: "124902244" },
+ { chr: "15", size: "104043685" },
+ { chr: "16", size: "98207768" },
+ { chr: "17", size: "94987271" },
+ { chr: "18", size: "90702639" },
+ { chr: "19", size: "61431566" },
+ ];
+
+var vscaleWidth = 90.0;
+var legendWidth = 140.0;
+
+if ('significant' in js_data) {
+ var significant_score = parseFloat(js_data.significant)
+} else {
+ var significant_score = 4
+}
+var score = { min: 0.0, max: js_data.max_score, sig: significant_score };
+var gwasPadding = { top: 35.0,
+ bottom: 35.0,
+ left: vscaleWidth,
+ right: legendWidth };
+var gwasHeight = 320.0;
+var config =
+{ score: score,
+ urls: localUrls,
+ tracks: {
+ gwas: {
+ trackHeight: gwasHeight,
+ padding: gwasPadding,
+ snps: {
+ radius: 3.75,
+ lineWidth: 1.0,
+ color: { outline: "#FFFFFF",
+ fill: "#00008B" },
+ pixelOffset: {x: 0.0, y: 0.0}
+ },
+ annotations: {
+ urls: {
+ url: "GeneNetwork"
+ },
+ radius: 5.5,
+ outline: "#000000",
+ snpColor: "#0074D9",
+ geneColor: "#FF4136"
+ },
+ score: score,
+ legend: {
+ fontSize: 14,
+ hPad: 0.2,
+ vPad: 0.2
+ },
+ vscale: {
+ color: "#000000",
+ hPad: 0.125,
+ numSteps: 3,
+ fonts: { labelSize: 18, scaleSize: 16 }
+ },
+ },
+ },
+ chrs: {
+ chrBG1: "#FFFFFF",
+ chrBG2: "#EEEEEE",
+ chrLabels: { fontSize: 16 },
+ },
+ // initialChrs: { left: "1", right: "5" }
+ coordinateSystem: coordinateSystem,
+ };
+
+GenomeBrowser.main(config)();
+
document.getElementById("controls").style.visibility = "visible";
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js
index cc4195e4..e8b7ab83 100644
--- a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js
+++ b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js
@@ -195,7 +195,6 @@
}
},
yaxis: {
- title: "Data Quantiles",
zeroline: false,
visible: true,
linecolor: 'black',
diff --git a/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript-genetics-browser.css b/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript-genetics-browser.css
new file mode 100644
index 00000000..135292ac
--- /dev/null
+++ b/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript-genetics-browser.css
@@ -0,0 +1 @@
+body,html{max-width:100%;overflow-x:hidden}#browser{position:absolute;margin:0}#info-line{border:1px solid #aaa;padding:2px;position:absolute;right:0;top:1px;min-width:14%;font-size:9pt}#controls{visibility:hidden;position:absolute;top:4px;left:100px;z-index:1000}#controls>button{border:1px solid #aaa;border-radius:2px;padding-left:6px;padding-right:6px;height:23px;min-width:20px}button#scrollRight,button#zoomIn{margin-left:-2px;margin-right:4px}#infoBox{position:absolute;display:inline-block;z-index:10000;visibility:hidden;padding:5px;border:2px solid grey;border-radius:5%;background-color:#fff;min-height:100px;min-width:10px;max-width:80%;margin-top:9.7em;font-family:sans-serif}#infoBox>div{float:left;margin:1em 1.2em}#infoBox>div>p{margin:.1em}
\ No newline at end of file
diff --git a/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript_genetics_browser_v01.css b/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript_genetics_browser_v01.css
deleted file mode 100644
index 135292ac..00000000
--- a/wqflask/wqflask/static/packages/purescript_genome_browser/css/purescript_genetics_browser_v01.css
+++ /dev/null
@@ -1 +0,0 @@
-body,html{max-width:100%;overflow-x:hidden}#browser{position:absolute;margin:0}#info-line{border:1px solid #aaa;padding:2px;position:absolute;right:0;top:1px;min-width:14%;font-size:9pt}#controls{visibility:hidden;position:absolute;top:4px;left:100px;z-index:1000}#controls>button{border:1px solid #aaa;border-radius:2px;padding-left:6px;padding-right:6px;height:23px;min-width:20px}button#scrollRight,button#zoomIn{margin-left:-2px;margin-right:4px}#infoBox{position:absolute;display:inline-block;z-index:10000;visibility:hidden;padding:5px;border:2px solid grey;border-radius:5%;background-color:#fff;min-height:100px;min-width:10px;max-width:80%;margin-top:9.7em;font-family:sans-serif}#infoBox>div{float:left;margin:1em 1.2em}#infoBox>div>p{margin:.1em}
\ No newline at end of file
diff --git a/wqflask/wqflask/static/packages/purescript_genome_browser/js/purescript-genetics-browser.js b/wqflask/wqflask/static/packages/purescript_genome_browser/js/purescript-genetics-browser.js
new file mode 100644
index 00000000..27bb4b2f
--- /dev/null
+++ b/wqflask/wqflask/static/packages/purescript_genome_browser/js/purescript-genetics-browser.js
@@ -0,0 +1,63016 @@
+// modules are defined as an array
+// [ module function, map of requires ]
+//
+// map of requires is short require name -> numeric require
+//
+// anything defined in a previous bundle is accessed via the
+// orig method which is the require for previous bundles
+parcelRequire = (function (modules, cache, entry, globalName) {
+ // Save the require from previous bundle to this closure if any
+ var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
+ var nodeRequire = typeof require === 'function' && require;
+
+ function newRequire(name, jumped) {
+ if (!cache[name]) {
+ if (!modules[name]) {
+ // if we cannot find the module within our internal map or
+ // cache jump to the current global require ie. the last bundle
+ // that was added to the page.
+ var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
+ if (!jumped && currentRequire) {
+ return currentRequire(name, true);
+ }
+
+ // If there are other bundles on this page the require from the
+ // previous one is saved to 'previousRequire'. Repeat this as
+ // many times as there are bundles until the module is found or
+ // we exhaust the require chain.
+ if (previousRequire) {
+ return previousRequire(name, true);
+ }
+
+ // Try the node require function if it exists.
+ if (nodeRequire && typeof name === 'string') {
+ return nodeRequire(name);
+ }
+
+ var err = new Error('Cannot find module \'' + name + '\'');
+ err.code = 'MODULE_NOT_FOUND';
+ throw err;
+ }
+
+ localRequire.resolve = resolve;
+ localRequire.cache = {};
+
+ var module = cache[name] = new newRequire.Module(name);
+
+ modules[name][0].call(module.exports, localRequire, module, module.exports, this);
+ }
+
+ return cache[name].exports;
+
+ function localRequire(x){
+ return newRequire(localRequire.resolve(x));
+ }
+
+ function resolve(x){
+ return modules[name][1][x] || x;
+ }
+ }
+
+ function Module(moduleName) {
+ this.id = moduleName;
+ this.bundle = newRequire;
+ this.exports = {};
+ }
+
+ newRequire.isParcelRequire = true;
+ newRequire.Module = Module;
+ newRequire.modules = modules;
+ newRequire.cache = cache;
+ newRequire.parent = previousRequire;
+ newRequire.register = function (id, exports) {
+ modules[id] = [function (require, module) {
+ module.exports = exports;
+ }, {}];
+ };
+
+ var error;
+ for (var i = 0; i < entry.length; i++) {
+ try {
+ newRequire(entry[i]);
+ } catch (e) {
+ // Save first error but execute all entries
+ if (!error) {
+ error = e;
+ }
+ }
+ }
+
+ if (entry.length) {
+ // Expose entry point to Node, AMD or browser globals
+ // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
+ var mainExports = newRequire(entry[entry.length - 1]);
+
+ // CommonJS
+ if (typeof exports === "object" && typeof module !== "undefined") {
+ module.exports = mainExports;
+
+ // RequireJS
+ } else if (typeof define === "function" && define.amd) {
+ define(function () {
+ return mainExports;
+ });
+
+ //
-
+