aboutsummaryrefslogtreecommitdiff
path: root/wqflask
diff options
context:
space:
mode:
authorzsloan2021-10-05 16:41:13 -0500
committerGitHub2021-10-05 16:41:13 -0500
commit70023c835bdeeffc48efafe96626ac5b01b5a6d2 (patch)
tree5e23e1139d2e01e2ad42969f58d148132db963a7 /wqflask
parentde79d0d5087bf97f59a16327132fd287d57e1c3f (diff)
parent4c6a7e46dd7afe311c0bed38c4a69ddadf3cb416 (diff)
downloadgenenetwork2-70023c835bdeeffc48efafe96626ac5b01b5a6d2.tar.gz
Merge branch 'testing' into feature/add_resizeable_columns
Diffstat (limited to 'wqflask')
-rw-r--r--wqflask/.DS_Storebin6148 -> 0 bytes
-rw-r--r--wqflask/base/data_set.py33
-rw-r--r--wqflask/base/trait.py25
-rw-r--r--wqflask/runserver.py3
-rw-r--r--wqflask/tests/integration/test_markdown_routes.py21
-rw-r--r--wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py20
-rw-r--r--wqflask/utility/Plot.py4
-rw-r--r--wqflask/utility/authentication_tools.py10
-rw-r--r--wqflask/utility/redis_tools.py20
-rw-r--r--wqflask/utility/startup_config.py6
-rw-r--r--wqflask/wqflask/correlation/correlation_functions.py39
-rw-r--r--wqflask/wqflask/correlation/correlation_gn3_api.py70
-rw-r--r--wqflask/wqflask/correlation/show_corr_results.py608
-rw-r--r--wqflask/wqflask/correlation_matrix/show_corr_matrix.py124
-rw-r--r--wqflask/wqflask/decorators.py28
-rw-r--r--wqflask/wqflask/marker_regression/display_mapping_results.py126
-rw-r--r--wqflask/wqflask/marker_regression/gemma_mapping.py35
-rw-r--r--wqflask/wqflask/marker_regression/qtlreaper_mapping.py95
-rw-r--r--wqflask/wqflask/marker_regression/rqtl_mapping.py7
-rw-r--r--wqflask/wqflask/marker_regression/run_mapping.py91
-rw-r--r--wqflask/wqflask/resource_manager.py2
-rw-r--r--wqflask/wqflask/show_trait/SampleList.py51
-rw-r--r--wqflask/wqflask/show_trait/show_trait.py60
-rw-r--r--wqflask/wqflask/static/new/css/bootstrap-custom.css4
-rw-r--r--wqflask/wqflask/static/new/css/show_trait.css36
-rw-r--r--wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js62
-rw-r--r--wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js6
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait.js95
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js10
-rw-r--r--wqflask/wqflask/templates/admin/group_manager.html2
-rw-r--r--wqflask/wqflask/templates/base.html3
-rw-r--r--wqflask/wqflask/templates/collections/add.html29
-rw-r--r--wqflask/wqflask/templates/collections/view.html2
-rw-r--r--wqflask/wqflask/templates/correlation_page.html16
-rw-r--r--wqflask/wqflask/templates/display_files_admin.html32
-rw-r--r--wqflask/wqflask/templates/display_files_user.html31
-rw-r--r--wqflask/wqflask/templates/edit_phenotype.html (renamed from wqflask/wqflask/templates/edit_trait.html)28
-rw-r--r--wqflask/wqflask/templates/edit_probeset.html239
-rw-r--r--wqflask/wqflask/templates/loading.html51
-rw-r--r--wqflask/wqflask/templates/mapping_results.html34
-rw-r--r--wqflask/wqflask/templates/new_security/_scripts.html1
-rw-r--r--wqflask/wqflask/templates/new_security/forgot_password.html1
-rw-r--r--wqflask/wqflask/templates/new_security/forgot_password_step2.html1
-rw-r--r--wqflask/wqflask/templates/new_security/login_user.html26
-rw-r--r--wqflask/wqflask/templates/new_security/password_reset.html1
-rw-r--r--wqflask/wqflask/templates/new_security/register_user.html1
-rw-r--r--wqflask/wqflask/templates/new_security/registered.html1
-rw-r--r--wqflask/wqflask/templates/new_security/thank_you.html1
-rw-r--r--wqflask/wqflask/templates/new_security/verification_still_needed.html1
-rw-r--r--wqflask/wqflask/templates/search_result_page.html8
-rw-r--r--wqflask/wqflask/templates/show_trait_calculate_correlations.html4
-rw-r--r--wqflask/wqflask/templates/show_trait_details.html11
-rwxr-xr-xwqflask/wqflask/templates/show_trait_mapping_tools.html55
-rw-r--r--wqflask/wqflask/templates/show_trait_transform_and_filter.html29
-rw-r--r--wqflask/wqflask/templates/test_correlation_page.html2
-rw-r--r--wqflask/wqflask/views.py403
56 files changed, 1576 insertions, 1128 deletions
diff --git a/wqflask/.DS_Store b/wqflask/.DS_Store
deleted file mode 100644
index d992942f..00000000
--- a/wqflask/.DS_Store
+++ /dev/null
Binary files differ
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 6dc44829..8906ab69 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -277,7 +277,6 @@ class Markers:
filtered_markers = []
for marker in self.markers:
if marker['name'] in p_values:
- # logger.debug("marker {} IS in p_values".format(i))
marker['p_value'] = p_values[marker['name']]
if math.isnan(marker['p_value']) or (marker['p_value'] <= 0):
marker['lod_score'] = 0
@@ -298,7 +297,6 @@ class HumanMarkers(Markers):
self.markers = []
for line in marker_data_fh:
splat = line.strip().split()
- # logger.debug("splat:", splat)
if len(specified_markers) > 0:
if splat[1] in specified_markers:
marker = {}
@@ -398,6 +396,15 @@ class DatasetGroup:
if maternal and paternal:
self.parlist = [maternal, paternal]
+ def get_study_samplelists(self):
+ study_sample_file = locate_ignore_error(self.name + ".json", 'study_sample_lists')
+ try:
+ f = open(study_sample_file)
+ except:
+ return []
+ study_samples = json.load(f)
+ return study_samples
+
def get_genofiles(self):
jsonfile = "%s/%s.json" % (webqtlConfig.GENODIR, self.name)
try:
@@ -557,6 +564,7 @@ class DataSet:
self.fullname = None
self.type = None
self.data_scale = None # ZS: For example log2
+ self.accession_id = None
self.setup()
@@ -573,6 +581,17 @@ class DataSet:
self.group.get_samplelist()
self.species = species.TheSpecies(self)
+ def as_dict(self):
+ return {
+ 'name': self.name,
+ 'shortname': self.shortname,
+ 'fullname': self.fullname,
+ 'type': self.type,
+ 'data_scale': self.data_scale,
+ 'group': self.group.name,
+ 'accession_id': self.accession_id
+ }
+
def get_accession_id(self):
if self.type == "Publish":
results = g.db.execute("""select InfoFiles.GN_AccesionId from InfoFiles, PublishFreeze, InbredSet where
@@ -725,7 +744,6 @@ class DataSet:
and Strain.SpeciesId=Species.Id
and Species.name = '{}'
""".format(create_in_clause(self.samplelist), *mescape(self.group.species))
- logger.sql(query)
results = dict(g.db.execute(query).fetchall())
sample_ids = [results[item] for item in self.samplelist]
@@ -896,7 +914,6 @@ class PhenotypeDataSet(DataSet):
Geno.Name = '%s' and
Geno.SpeciesId = Species.Id
""" % (species, this_trait.locus)
- logger.sql(query)
result = g.db.execute(query).fetchone()
if result:
@@ -926,7 +943,6 @@ class PhenotypeDataSet(DataSet):
Order BY
Strain.Name
"""
- logger.sql(query)
results = g.db.execute(query, (trait, self.id)).fetchall()
return results
@@ -993,7 +1009,6 @@ class GenotypeDataSet(DataSet):
Order BY
Strain.Name
"""
- logger.sql(query)
results = g.db.execute(query,
(webqtlDatabaseFunction.retrieve_species_id(self.group.name),
trait, self.name)).fetchall()
@@ -1114,8 +1129,6 @@ class MrnaAssayDataSet(DataSet):
ProbeSet.Name = '%s'
""" % (escape(str(this_trait.dataset.id)),
escape(this_trait.name)))
-
- logger.sql(query)
result = g.db.execute(query).fetchone()
mean = result[0] if result else 0
@@ -1135,7 +1148,6 @@ class MrnaAssayDataSet(DataSet):
Geno.Name = '{}' and
Geno.SpeciesId = Species.Id
""".format(species, this_trait.locus)
- logger.sql(query)
result = g.db.execute(query).fetchone()
if result:
@@ -1167,7 +1179,6 @@ class MrnaAssayDataSet(DataSet):
Order BY
Strain.Name
""" % (escape(trait), escape(self.name))
- logger.sql(query)
results = g.db.execute(query).fetchall()
return results
@@ -1178,7 +1189,6 @@ class MrnaAssayDataSet(DataSet):
where ProbeSetXRef.ProbeSetFreezeId = %s and
ProbeSetXRef.ProbeSetId=ProbeSet.Id;
""" % (column_name, escape(str(self.id)))
- logger.sql(query)
results = g.db.execute(query).fetchall()
return dict(results)
@@ -1212,7 +1222,6 @@ def geno_mrna_confidentiality(ob):
query = '''SELECT Id, Name, FullName, confidentiality,
AuthorisedUsers FROM %s WHERE Name = "%s"''' % (dataset_table, ob.name)
- logger.sql(query)
result = g.db.execute(query)
(dataset_id,
diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py
index d09cfd40..96a09302 100644
--- a/wqflask/base/trait.py
+++ b/wqflask/base/trait.py
@@ -27,11 +27,13 @@ def create_trait(**kw):
assert bool(kw.get('name')), "Needs trait name"
- if kw.get('dataset_name'):
+ if bool(kw.get('dataset')):
+ dataset = kw.get('dataset')
+ else:
if kw.get('dataset_name') != "Temp":
dataset = create_dataset(kw.get('dataset_name'))
- else:
- dataset = kw.get('dataset')
+ else:
+ dataset = create_dataset("Temp", group_name=kw.get('group_name'))
if dataset.type == 'Publish':
permissions = check_resource_availability(
@@ -284,17 +286,19 @@ def get_sample_data():
return None
-def jsonable(trait):
+def jsonable(trait, dataset=None):
"""Return a dict suitable for using as json
Actual turning into json doesn't happen here though"""
- dataset = create_dataset(dataset_name=trait.dataset.name,
- dataset_type=trait.dataset.type,
- group_name=trait.dataset.group.name)
+ if not dataset:
+ dataset = create_dataset(dataset_name=trait.dataset.name,
+ dataset_type=trait.dataset.type,
+ group_name=trait.dataset.group.name)
if dataset.type == "ProbeSet":
return dict(name=trait.name,
+ view=trait.view,
symbol=trait.symbol,
dataset=dataset.name,
dataset_name=dataset.shortname,
@@ -308,37 +312,44 @@ def jsonable(trait):
elif dataset.type == "Publish":
if trait.pubmed_id:
return dict(name=trait.name,
+ view=trait.view,
dataset=dataset.name,
dataset_name=dataset.shortname,
description=trait.description_display,
abbreviation=trait.abbreviation,
authors=trait.authors,
+ pubmed_id=trait.pubmed_id,
pubmed_text=trait.pubmed_text,
pubmed_link=trait.pubmed_link,
+ mean=trait.mean,
lrs_score=trait.LRS_score_repr,
lrs_location=trait.LRS_location_repr,
additive=trait.additive
)
else:
return dict(name=trait.name,
+ view=trait.view,
dataset=dataset.name,
dataset_name=dataset.shortname,
description=trait.description_display,
abbreviation=trait.abbreviation,
authors=trait.authors,
pubmed_text=trait.pubmed_text,
+ mean=trait.mean,
lrs_score=trait.LRS_score_repr,
lrs_location=trait.LRS_location_repr,
additive=trait.additive
)
elif dataset.type == "Geno":
return dict(name=trait.name,
+ view=trait.view,
dataset=dataset.name,
dataset_name=dataset.shortname,
location=trait.location_repr
)
elif dataset.name == "Temp":
return dict(name=trait.name,
+ view=trait.view,
dataset="Temp",
dataset_name="Temp")
else:
diff --git a/wqflask/runserver.py b/wqflask/runserver.py
index df957bd9..8198b921 100644
--- a/wqflask/runserver.py
+++ b/wqflask/runserver.py
@@ -23,6 +23,9 @@ app_config()
werkzeug_logger = logging.getLogger('werkzeug')
if WEBSERVER_MODE == 'DEBUG':
+ from flask_debugtoolbar import DebugToolbarExtension
+ app.debug = True
+ toolbar = DebugToolbarExtension(app)
app.run(host='0.0.0.0',
port=SERVER_PORT,
debug=True,
diff --git a/wqflask/tests/integration/test_markdown_routes.py b/wqflask/tests/integration/test_markdown_routes.py
deleted file mode 100644
index 5e3e5045..00000000
--- a/wqflask/tests/integration/test_markdown_routes.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"Integration tests for markdown routes"
-import unittest
-
-from bs4 import BeautifulSoup
-
-from wqflask import app
-
-
-class TestGenMenu(unittest.TestCase):
- """Tests for glossary"""
-
- def setUp(self):
- self.app = app.test_client()
-
- def tearDown(self):
- pass
-
- def test_glossary_page(self):
- """Test that the glossary page is rendered properly"""
- response = self.app.get('/glossary', follow_redirects=True)
- pass
diff --git a/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py
index 2bbeab1f..a8cf6006 100644
--- a/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py
+++ b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py
@@ -1,10 +1,30 @@
+"""module contains tests for correlation functions"""
+
import unittest
from unittest import mock
+
from wqflask.correlation.correlation_functions import get_trait_symbol_and_tissue_values
from wqflask.correlation.correlation_functions import cal_zero_order_corr_for_tiss
class TestCorrelationFunctions(unittest.TestCase):
+ """test for correlation helper functions"""
+
+ @mock.patch("wqflask.correlation.correlation_functions.compute_corr_coeff_p_value")
+ def test_tissue_corr_computation(self, mock_tiss_corr_computation):
+ """test for cal_zero_order_corr_for_tiss"""
+
+ primary_values = [9.288, 9.313, 8.988, 9.660, 8.21]
+ target_values = [9.586, 8.498, 9.362, 8.820, 8.786]
+
+ mock_tiss_corr_computation.return_value = (0.51, 0.7)
+
+ results = cal_zero_order_corr_for_tiss(primary_values, target_values)
+ mock_tiss_corr_computation.assert_called_once_with(
+ primary_values=primary_values, target_values=target_values,
+ corr_method="pearson")
+
+ self.assertEqual(len(results), 3)
@mock.patch("wqflask.correlation.correlation_functions.MrnaAssayTissueData")
def test_get_trait_symbol_and_tissue_values(self, mock_class):
diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py
index 9b2c6735..d4256a46 100644
--- a/wqflask/utility/Plot.py
+++ b/wqflask/utility/Plot.py
@@ -139,7 +139,7 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab
max_D = max(data)
min_D = min(data)
# add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong
- if max_D == float('inf') or max_D > webqtlConfig.MAXLRS:
+ if (max_D == float('inf') or max_D > webqtlConfig.MAXLRS) and min_D < webqtlConfig.MAXLRS:
max_D = webqtlConfig.MAXLRS # maximum LRS value
xLow, xTop, stepX = detScale(min_D, max_D)
@@ -156,7 +156,7 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab
j += step
for i, item in enumerate(data):
- if item == float('inf') or item > webqtlConfig.MAXLRS:
+ if (item == float('inf') or item > webqtlConfig.MAXLRS) and min_D < webqtlConfig.MAXLRS:
item = webqtlConfig.MAXLRS # maximum LRS value
j = int((item - xLow) / step)
Count[j] += 1
diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py
index 57dbf8ba..6802d689 100644
--- a/wqflask/utility/authentication_tools.py
+++ b/wqflask/utility/authentication_tools.py
@@ -11,7 +11,6 @@ from utility.redis_tools import (get_redis_conn,
add_resource)
Redis = get_redis_conn()
-
def check_resource_availability(dataset, trait_id=None):
# At least for now assume temporary entered traits are accessible
if type(dataset) == str or dataset.type == "Temp":
@@ -133,12 +132,17 @@ def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None):
else:
resource_id = get_resource_id(dataset, trait_id)
- if g.user_session.user_id in Redis.smembers("super_users"):
+ try:
+ user_id = g.user_session.user_id.encode('utf-8')
+ except:
+ user_id = g.user_session.user_id
+
+ if user_id in Redis.smembers("super_users"):
return "owner"
resource_info = get_resource_info(resource_id)
if resource_info:
- if g.user_session.user_id == resource_info['owner_id']:
+ if user_id == resource_info['owner_id']:
return "owner"
else:
return check_admin(resource_id)
diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py
index ff125bd2..de9dde46 100644
--- a/wqflask/utility/redis_tools.py
+++ b/wqflask/utility/redis_tools.py
@@ -127,22 +127,20 @@ def check_verification_code(code):
def get_user_groups(user_id):
- # ZS: Get the groups where a user is an admin or a member and
+ # Get the groups where a user is an admin or a member and
# return lists corresponding to those two sets of groups
- admin_group_ids = [] # ZS: Group IDs where user is an admin
- user_group_ids = [] # ZS: Group IDs where user is a regular user
+ admin_group_ids = [] # Group IDs where user is an admin
+ user_group_ids = [] # Group IDs where user is a regular user
groups_list = Redis.hgetall("groups")
- for key in groups_list:
+ for group_id, group_details in groups_list.items():
try:
- group_ob = json.loads(groups_list[key])
- group_admins = set([this_admin.encode(
- 'utf-8') if this_admin else None for this_admin in group_ob['admins']])
- group_members = set([this_member.encode(
- 'utf-8') if this_member else None for this_member in group_ob['members']])
+ _details = json.loads(group_details)
+ group_admins = set([this_admin if this_admin else None for this_admin in _details['admins']])
+ group_members = set([this_member if this_member else None for this_member in _details['members']])
if user_id in group_admins:
- admin_group_ids.append(group_ob['id'])
+ admin_group_ids.append(group_id)
elif user_id in group_members:
- user_group_ids.append(group_ob['id'])
+ user_group_ids.append(group_id)
else:
continue
except:
diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py
index 56d0af6f..778fb64d 100644
--- a/wqflask/utility/startup_config.py
+++ b/wqflask/utility/startup_config.py
@@ -20,8 +20,12 @@ def app_config():
import os
app.config['SECRET_KEY'] = str(os.urandom(24))
mode = WEBSERVER_MODE
- if mode == "DEV" or mode == "DEBUG":
+ if mode in ["DEV", "DEBUG"]:
app.config['TEMPLATES_AUTO_RELOAD'] = True
+ if mode == "DEBUG":
+ from flask_debugtoolbar import DebugToolbarExtension
+ app.debug = True
+ toolbar = DebugToolbarExtension(app)
print("==========================================")
diff --git a/wqflask/wqflask/correlation/correlation_functions.py b/wqflask/wqflask/correlation/correlation_functions.py
index c8b9da0e..85b25d60 100644
--- a/wqflask/wqflask/correlation/correlation_functions.py
+++ b/wqflask/wqflask/correlation/correlation_functions.py
@@ -21,15 +21,10 @@
# This module is used by GeneNetwork project (www.genenetwork.org)
#
# Created by GeneNetwork Core Team 2010/08/10
-#
-# Last updated by NL 2011/03/23
-import math
-import string
from base.mrna_assay_tissue_data import MrnaAssayTissueData
-
-from flask import Flask, g
+from gn3.computations.correlations import compute_corr_coeff_p_value
#####################################################################################
@@ -45,31 +40,14 @@ from flask import Flask, g
# the same tissue order
#####################################################################################
-def cal_zero_order_corr_for_tiss(primaryValue=[], targetValue=[], method='pearson'):
-
- N = len(primaryValue)
- # R_primary = rpy2.robjects.FloatVector(list(range(len(primaryValue))))
- # for i in range(len(primaryValue)):
- # R_primary[i] = primaryValue[i]
- # R_target = rpy2.robjects.FloatVector(list(range(len(targetValue))))
- # for i in range(len(targetValue)):
- # R_target[i] = targetValue[i]
+def cal_zero_order_corr_for_tiss(primary_values, target_values, method="pearson"):
+ """function use calls gn3 to compute corr,p_val"""
- # R_corr_test = rpy2.robjects.r['cor.test']
- # if method == 'spearman':
- # R_result = R_corr_test(R_primary, R_target, method='spearman')
- # else:
- # R_result = R_corr_test(R_primary, R_target)
-
- # corr_result = []
- # corr_result.append(R_result[3][0])
- # corr_result.append(N)
- # corr_result.append(R_result[2][0])
-
- return [None, N, None]
- # return corr_result
+ (corr_coeff, p_val) = compute_corr_coeff_p_value(
+ primary_values=primary_values, target_values=target_values, corr_method=method)
+ return (corr_coeff, len(primary_values), p_val)
########################################################################################################
# input: cursor, symbolList (list), dataIdDict(Dict): key is symbol
@@ -80,8 +58,9 @@ def cal_zero_order_corr_for_tiss(primaryValue=[], targetValue=[], method='pearso
# then call getSymbolValuePairDict function and merge the results.
########################################################################################################
+
def get_trait_symbol_and_tissue_values(symbol_list=None):
tissue_data = MrnaAssayTissueData(gene_symbols=symbol_list)
- if len(tissue_data.gene_symbols) >0:
+ if len(tissue_data.gene_symbols) > 0:
results = tissue_data.get_symbol_values_pairs()
- return results
+ return results
diff --git a/wqflask/wqflask/correlation/correlation_gn3_api.py b/wqflask/wqflask/correlation/correlation_gn3_api.py
index 30c05f03..a18bceaf 100644
--- a/wqflask/wqflask/correlation/correlation_gn3_api.py
+++ b/wqflask/wqflask/correlation/correlation_gn3_api.py
@@ -18,7 +18,10 @@ from gn3.db_utils import database_connector
def create_target_this_trait(start_vars):
"""this function creates the required trait and target dataset for correlation"""
- this_dataset = data_set.create_dataset(dataset_name=start_vars['dataset'])
+ if start_vars['dataset'] == "Temp":
+ this_dataset = data_set.create_dataset(dataset_name="Temp", dataset_type="Temp", group_name=start_vars['group'])
+ else:
+ this_dataset = data_set.create_dataset(dataset_name=start_vars['dataset'])
target_dataset = data_set.create_dataset(
dataset_name=start_vars['corr_dataset'])
this_trait = create_trait(dataset=this_dataset,
@@ -145,15 +148,9 @@ def lit_for_trait_list(corr_results, this_dataset, this_trait):
def fetch_sample_data(start_vars, this_trait, this_dataset, target_dataset):
sample_data = process_samples(
- start_vars, this_dataset.group.samplelist)
-
- sample_data = test_process_data(this_trait, this_dataset, start_vars)
-
+ start_vars, this_dataset.group.all_samples_ordered())
- if target_dataset.type == "ProbeSet":
- target_dataset.get_probeset_data(list(sample_data.keys()))
- else:
- target_dataset.get_trait_data(list(sample_data.keys()))
+ target_dataset.get_trait_data(list(sample_data.keys()))
this_trait = retrieve_sample_data(this_trait, this_dataset)
this_trait_data = {
"trait_sample_data": sample_data,
@@ -165,8 +162,14 @@ def fetch_sample_data(start_vars, this_trait, this_dataset, target_dataset):
return (this_trait_data, results)
-def compute_correlation(start_vars, method="pearson"):
- """compute correlation for to call gn3 api"""
+def compute_correlation(start_vars, method="pearson", compute_all=False):
+ """Compute correlations using GN3 API
+
+ Keyword arguments:
+ start_vars -- All input from form; includes things like the trait/dataset names
+ method -- Correlation method to be used (pearson, spearman, or bicor)
+ compute_all -- Include sample, tissue, and literature correlations (when applicable)
+ """
# pylint: disable-msg=too-many-locals
corr_type = start_vars['corr_type']
@@ -196,17 +199,22 @@ def compute_correlation(start_vars, method="pearson"):
if tissue_input is not None:
(primary_tissue_data, target_tissue_data) = tissue_input
- corr_input_data = {
- "primary_tissue": primary_tissue_data,
- "target_tissues_dict": target_tissue_data
- }
- correlation_results = compute_tissue_correlation(
- primary_tissue_dict=corr_input_data["primary_tissue"],
- target_tissues_data=corr_input_data[
- "target_tissues_dict"],
- corr_method=method
-
- )
+ corr_input_data = {
+ "primary_tissue": primary_tissue_data,
+ "target_tissues_dict": target_tissue_data
+ }
+ correlation_results = compute_tissue_correlation(
+ primary_tissue_dict=corr_input_data["primary_tissue"],
+ target_tissues_data=corr_input_data[
+ "target_tissues_dict"],
+ corr_method=method
+
+ )
+ else:
+ return {"correlation_results": [],
+ "this_trait": this_trait.name,
+ "target_dataset": start_vars['corr_dataset'],
+ "return_results": corr_return_results}
elif corr_type == "lit":
(this_trait_geneid, geneid_dict, species) = do_lit_correlation(
@@ -220,11 +228,9 @@ def compute_correlation(start_vars, method="pearson"):
correlation_results = correlation_results[0:corr_return_results]
- compute_all = True # later to be passed as argument
-
if (compute_all):
-
- correlation_results = compute_corr_for_top_results(correlation_results,
+ correlation_results = compute_corr_for_top_results(start_vars,
+ correlation_results,
this_trait,
this_dataset,
target_dataset,
@@ -238,7 +244,8 @@ def compute_correlation(start_vars, method="pearson"):
return correlation_data
-def compute_corr_for_top_results(correlation_results,
+def compute_corr_for_top_results(start_vars,
+ correlation_results,
this_trait,
this_dataset,
target_dataset,
@@ -261,8 +268,12 @@ def compute_corr_for_top_results(correlation_results,
correlation_results = merge_correlation_results(
correlation_results, lit_result)
- if corr_type != "sample":
- pass
+ if corr_type != "sample" and this_dataset.type == "ProbeSet" and target_dataset.type == "ProbeSet":
+ sample_result = sample_for_trait_lists(
+ correlation_results, target_dataset, this_trait, this_dataset, start_vars)
+ if sample_result:
+ correlation_results = merge_correlation_results(
+ correlation_results, sample_result)
return correlation_results
@@ -294,4 +305,3 @@ def get_tissue_correlation_input(this_trait, trait_symbol_dict):
"symbol_tissue_vals_dict": corr_result_tissue_vals_dict
}
return (primary_tissue_data, target_tissue_data)
- return None
diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py
index 2f3df67a..d73965da 100644
--- a/wqflask/wqflask/correlation/show_corr_results.py
+++ b/wqflask/wqflask/correlation/show_corr_results.py
@@ -18,491 +18,152 @@
#
# This module is used by GeneNetwork project (www.genenetwork.org)
-import collections
import json
-import scipy
-import numpy
-# import rpy2.robjects as ro # R Objects
-import utility.logger
-import utility.webqtlUtil
-from base.trait import create_trait
+from base.trait import create_trait, jsonable
+from base.data_set import create_dataset
-from base import data_set
-from utility import helper_functions
-from utility import corr_result_helpers
from utility import hmac
-from wqflask.correlation import correlation_functions
-from utility.benchmark import Bench
-
-from utility.type_checking import is_str
-from utility.type_checking import get_float
-from utility.type_checking import get_int
-from utility.type_checking import get_string
-from utility.db_tools import escape
-
-from flask import g
-
-logger = utility.logger.getLogger(__name__)
-
-METHOD_LIT = "3"
-METHOD_TISSUE_PEARSON = "4"
-METHOD_TISSUE_RANK = "5"
-
-TISSUE_METHODS = [METHOD_TISSUE_PEARSON, METHOD_TISSUE_RANK]
-
-TISSUE_MOUSE_DB = 1
-
-
-class CorrelationResults:
- def __init__(self, start_vars):
- # get trait list from db (database name)
- # calculate correlation with Base vector and targets
-
- # 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('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":
- self.dataset = data_set.create_dataset(
- dataset_name="Temp", dataset_type="Temp", group_name=start_vars['group'])
- self.trait_id = start_vars['trait_id']
- self.this_trait = create_trait(dataset=self.dataset,
- name=self.trait_id,
- cellid=None)
- else:
- helper_functions.get_species_dataset_trait(self, start_vars)
-
- corr_samples_group = start_vars['corr_samples_group']
-
- self.sample_data = {}
- self.corr_type = start_vars['corr_type']
- self.corr_method = start_vars['corr_sample_method']
- 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_type = get_string(start_vars, 'location_type')
- 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')
- else:
- self.location_type = self.location_chr = self.min_location_mb = self.max_location_mb = None
-
- self.get_formatted_corr_type()
- self.return_number = int(start_vars['corr_return_results'])
-
- # The two if statements below append samples to the sample list based upon whether the user
- # rselected Primary Samples Only, Other Samples Only, or All Samples
-
- primary_samples = self.dataset.group.samplelist
- if self.dataset.group.parlist != None:
- primary_samples += self.dataset.group.parlist
- if self.dataset.group.f1list != None:
- primary_samples += self.dataset.group.f1list
-
- # If either BXD/whatever Only or All Samples, append all of that group's samplelist
- if corr_samples_group != 'samples_other':
- self.process_samples(start_vars, primary_samples)
-
- # If either Non-BXD/whatever or All Samples, get all samples from this_trait.data and
- # exclude the primary samples (because they would have been added in the previous
- # if statement if the user selected All Samples)
- if corr_samples_group != 'samples_primary':
- if corr_samples_group == 'samples_other':
- primary_samples = [x for x in primary_samples if x not in (
- self.dataset.group.parlist + self.dataset.group.f1list)]
- self.process_samples(start_vars, list(
- self.this_trait.data.keys()), primary_samples)
-
- self.target_dataset = data_set.create_dataset(
- start_vars['corr_dataset'])
- self.target_dataset.get_trait_data(list(self.sample_data.keys()))
-
- self.header_fields = get_header_fields(
- self.target_dataset.type, self.corr_method)
-
- if self.target_dataset.type == "ProbeSet":
- self.filter_cols = [7, 6]
- elif self.target_dataset.type == "Publish":
- self.filter_cols = [6, 0]
- else:
- self.filter_cols = [4, 0]
+def set_template_vars(start_vars, correlation_data):
+ corr_type = start_vars['corr_type']
+ corr_method = start_vars['corr_sample_method']
- self.correlation_results = []
+ if start_vars['dataset'] == "Temp":
+ this_dataset_ob = create_dataset(dataset_name="Temp", dataset_type="Temp", group_name=start_vars['group'])
+ else:
+ this_dataset_ob = create_dataset(dataset_name=start_vars['dataset'])
+ this_trait = create_trait(dataset=this_dataset_ob,
+ name=start_vars['trait_id'])
- self.correlation_data = {}
+ correlation_data['this_trait'] = jsonable(this_trait, this_dataset_ob)
+ correlation_data['this_dataset'] = this_dataset_ob.as_dict()
- if self.corr_type == "tissue":
- self.trait_symbol_dict = self.dataset.retrieve_genes("Symbol")
+ target_dataset_ob = create_dataset(correlation_data['target_dataset'])
+ correlation_data['target_dataset'] = target_dataset_ob.as_dict()
- tissue_corr_data = self.do_tissue_correlation_for_all_traits()
- if tissue_corr_data != None:
- for trait in list(tissue_corr_data.keys())[:self.return_number]:
- self.get_sample_r_and_p_values(
- trait, self.target_dataset.trait_data[trait])
- else:
- for trait, values in list(self.target_dataset.trait_data.items()):
- 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()
-
- for trait in list(lit_corr_data.keys())[:self.return_number]:
- self.get_sample_r_and_p_values(
- trait, self.target_dataset.trait_data[trait])
-
- elif self.corr_type == "sample":
- for trait, values in list(self.target_dataset.trait_data.items()):
- self.get_sample_r_and_p_values(trait, values)
-
- self.correlation_data = collections.OrderedDict(sorted(list(self.correlation_data.items()),
- key=lambda t: -abs(t[1][0])))
-
- # ZS: Convert min/max chromosome to an int for the location range option
- range_chr_as_int = None
- for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()):
- if 'loc_chr' in start_vars:
- if chr_info.name == self.location_chr:
- range_chr_as_int = order_id
-
- for _trait_counter, trait in enumerate(list(self.correlation_data.keys())[:self.return_number]):
- trait_object = create_trait(
- dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False)
- if not trait_object:
- continue
-
- chr_as_int = 0
- for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()):
- if self.location_type == "highest_lod":
- if chr_info.name == trait_object.locus_chr:
- chr_as_int = order_id
- else:
- if chr_info.name == trait_object.chr:
- chr_as_int = order_id
-
-
- if (float(self.correlation_data[trait][0]) >= self.p_range_lower
- and float(self.correlation_data[trait][0]) <= self.p_range_upper):
-
- if (self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Publish") and bool(trait_object.mean):
- if (self.min_expr != None) and (float(trait_object.mean) < self.min_expr):
- continue
-
- if range_chr_as_int != None and (chr_as_int != range_chr_as_int):
- continue
- if self.location_type == "highest_lod":
- if (self.min_location_mb != None) and (float(trait_object.locus_mb) < float(self.min_location_mb)):
- continue
- if (self.max_location_mb != None) and (float(trait_object.locus_mb) > float(self.max_location_mb)):
- continue
- else:
- if (self.min_location_mb != None) and (float(trait_object.mb) < float(self.min_location_mb)):
- continue
- if (self.max_location_mb != None) and (float(trait_object.mb) > float(self.max_location_mb)):
- continue
-
- (trait_object.sample_r,
- trait_object.sample_p,
- trait_object.num_overlap) = self.correlation_data[trait]
-
- # Set some sane defaults
- trait_object.tissue_corr = 0
- trait_object.tissue_pvalue = 0
- trait_object.lit_corr = 0
- if self.corr_type == "tissue" and tissue_corr_data != None:
- trait_object.tissue_corr = tissue_corr_data[trait][1]
- trait_object.tissue_pvalue = tissue_corr_data[trait][2]
- elif self.corr_type == "lit":
- trait_object.lit_corr = lit_corr_data[trait][1]
-
- self.correlation_results.append(trait_object)
-
- if self.corr_type != "lit" and self.dataset.type == "ProbeSet" and self.target_dataset.type == "ProbeSet":
- self.do_lit_correlation_for_trait_list()
-
- if self.corr_type != "tissue" and self.dataset.type == "ProbeSet" and self.target_dataset.type == "ProbeSet":
- self.do_tissue_correlation_for_trait_list()
-
- self.json_results = generate_corr_json(
- self.correlation_results, self.this_trait, self.dataset, self.target_dataset)
-
-############################################################################################################################################
-
- def get_formatted_corr_type(self):
- self.formatted_corr_type = ""
- if self.corr_type == "lit":
- self.formatted_corr_type += "Literature Correlation "
- elif self.corr_type == "tissue":
- self.formatted_corr_type += "Tissue Correlation "
- elif self.corr_type == "sample":
- self.formatted_corr_type += "Genetic Correlation "
-
- if self.corr_method == "pearson":
- self.formatted_corr_type += "(Pearson's r)"
- elif self.corr_method == "spearman":
- self.formatted_corr_type += "(Spearman's rho)"
- elif self.corr_method == "bicor":
- self.formatted_corr_type += "(Biweight r)"
-
- def do_tissue_correlation_for_trait_list(self, tissue_dataset_id=1):
- """Given a list of correlation results (self.correlation_results), gets the tissue correlation value for each"""
-
- # Gets tissue expression values for the primary trait
- primary_trait_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(
- symbol_list=[self.this_trait.symbol])
-
- if self.this_trait.symbol.lower() in primary_trait_tissue_vals_dict:
- primary_trait_tissue_values = primary_trait_tissue_vals_dict[self.this_trait.symbol.lower(
- )]
- gene_symbol_list = [
- trait.symbol for trait in self.correlation_results if trait.symbol]
-
- corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(
- symbol_list=gene_symbol_list)
-
- for trait in self.correlation_results:
- if trait.symbol and trait.symbol.lower() in corr_result_tissue_vals_dict:
- this_trait_tissue_values = corr_result_tissue_vals_dict[trait.symbol.lower(
- )]
-
- result = correlation_functions.cal_zero_order_corr_for_tiss(primary_trait_tissue_values,
- this_trait_tissue_values,
- self.corr_method)
-
- trait.tissue_corr = result[0]
- trait.tissue_pvalue = result[2]
-
- def do_tissue_correlation_for_all_traits(self, tissue_dataset_id=1):
- # Gets tissue expression values for the primary trait
- primary_trait_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(
- symbol_list=[self.this_trait.symbol])
-
- if self.this_trait.symbol.lower() in primary_trait_tissue_vals_dict:
- primary_trait_tissue_values = primary_trait_tissue_vals_dict[self.this_trait.symbol.lower(
- )]
-
- #print("trait_gene_symbols: ", pf(trait_gene_symbols.values()))
- corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(
- symbol_list=list(self.trait_symbol_dict.values()))
-
- #print("corr_result_tissue_vals: ", pf(corr_result_tissue_vals_dict))
-
- #print("trait_gene_symbols: ", pf(trait_gene_symbols))
-
- tissue_corr_data = {}
- for trait, symbol in list(self.trait_symbol_dict.items()):
- if symbol and symbol.lower() in corr_result_tissue_vals_dict:
- this_trait_tissue_values = corr_result_tissue_vals_dict[symbol.lower(
- )]
+ table_json = correlation_json_for_table(correlation_data,
+ correlation_data['this_trait'],
+ correlation_data['this_dataset'],
+ target_dataset_ob)
- result = correlation_functions.cal_zero_order_corr_for_tiss(primary_trait_tissue_values,
- this_trait_tissue_values,
- self.corr_method)
+ correlation_data['table_json'] = table_json
- tissue_corr_data[trait] = [symbol, result[0], result[2]]
+ if target_dataset_ob.type == "ProbeSet":
+ filter_cols = [7, 6]
+ elif target_dataset_ob.type == "Publish":
+ filter_cols = [6, 0]
+ else:
+ filter_cols = [4, 0]
- tissue_corr_data = collections.OrderedDict(sorted(list(tissue_corr_data.items()),
- key=lambda t: -abs(t[1][1])))
+ correlation_data['corr_method'] = corr_method
+ correlation_data['filter_cols'] = filter_cols
+ correlation_data['header_fields'] = get_header_fields(
+ target_dataset_ob.type, correlation_data['corr_method'])
+ correlation_data['formatted_corr_type'] = get_formatted_corr_type(
+ corr_type, corr_method)
- return tissue_corr_data
+ return correlation_data
- def do_lit_correlation_for_trait_list(self):
- input_trait_mouse_gene_id = self.convert_to_mouse_gene_id(
- self.dataset.group.species.lower(), self.this_trait.geneid)
+def correlation_json_for_table(correlation_data, this_trait, this_dataset, target_dataset_ob):
+ """Return JSON data for use with the DataTable in the correlation result page
- for trait in self.correlation_results:
+ Keyword arguments:
+ correlation_data -- Correlation results
+ this_trait -- Trait being correlated against a dataset, as a dict
+ this_dataset -- Dataset of this_trait, as a dict
+ target_dataset_ob - Target dataset, as a Dataset ob
+ """
+ this_trait = correlation_data['this_trait']
+ this_dataset = correlation_data['this_dataset']
+ target_dataset = target_dataset_ob.as_dict()
- if trait.geneid:
- trait.mouse_gene_id = self.convert_to_mouse_gene_id(
- self.dataset.group.species.lower(), trait.geneid)
- else:
- trait.mouse_gene_id = None
-
- if trait.mouse_gene_id and str(trait.mouse_gene_id).find(";") == -1:
- result = g.db.execute(
- """SELECT value
- FROM LCorrRamin3
- WHERE GeneId1='%s' and
- GeneId2='%s'
- """ % (escape(str(trait.mouse_gene_id)), escape(str(input_trait_mouse_gene_id)))
- ).fetchone()
- if not result:
- result = g.db.execute("""SELECT value
- FROM LCorrRamin3
- WHERE GeneId2='%s' and
- GeneId1='%s'
- """ % (escape(str(trait.mouse_gene_id)), escape(str(input_trait_mouse_gene_id)))
- ).fetchone()
-
- if result:
- lit_corr = result.value
- trait.lit_corr = lit_corr
- else:
- trait.lit_corr = 0
- else:
- trait.lit_corr = 0
-
- def do_lit_correlation_for_all_traits(self):
- input_trait_mouse_gene_id = self.convert_to_mouse_gene_id(
- self.dataset.group.species.lower(), self.this_trait.geneid)
-
- lit_corr_data = {}
- for trait, gene_id in list(self.trait_geneid_dict.items()):
- mouse_gene_id = self.convert_to_mouse_gene_id(
- self.dataset.group.species.lower(), gene_id)
-
- if mouse_gene_id and str(mouse_gene_id).find(";") == -1:
- #print("gene_symbols:", input_trait_mouse_gene_id + " / " + mouse_gene_id)
- result = g.db.execute(
- """SELECT value
- FROM LCorrRamin3
- WHERE GeneId1='%s' and
- GeneId2='%s'
- """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id))
- ).fetchone()
- if not result:
- result = g.db.execute("""SELECT value
- FROM LCorrRamin3
- WHERE GeneId2='%s' and
- GeneId1='%s'
- """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id))
- ).fetchone()
- if result:
- #print("result:", result)
- lit_corr = result.value
- lit_corr_data[trait] = [gene_id, lit_corr]
+ corr_results = correlation_data['correlation_results']
+ results_list = []
+ for i, trait_dict in enumerate(corr_results):
+ trait_name = list(trait_dict.keys())[0]
+ trait = trait_dict[trait_name]
+ target_trait_ob = create_trait(dataset=target_dataset_ob,
+ name=trait_name,
+ get_qtl_info=True)
+ target_trait = jsonable(target_trait_ob, target_dataset_ob)
+ if target_trait['view'] == False:
+ continue
+ results_dict = {}
+ results_dict['index'] = i + 1
+ results_dict['trait_id'] = target_trait['name']
+ results_dict['dataset'] = target_dataset['name']
+ results_dict['hmac'] = hmac.data_hmac(
+ '{}:{}'.format(target_trait['name'], target_dataset['name']))
+ results_dict['sample_r'] = f"{float(trait['corr_coefficient']):.3f}"
+ results_dict['num_overlap'] = trait['num_overlap']
+ results_dict['sample_p'] = f"{float(trait['p_value']):.3e}"
+ if target_dataset['type'] == "ProbeSet":
+ results_dict['symbol'] = target_trait['symbol']
+ results_dict['description'] = "N/A"
+ results_dict['location'] = target_trait['location']
+ results_dict['mean'] = "N/A"
+ results_dict['additive'] = "N/A"
+ if bool(target_trait['description']):
+ results_dict['description'] = target_trait['description']
+ if bool(target_trait['mean']):
+ results_dict['mean'] = f"{float(target_trait['mean']):.3f}"
+ try:
+ results_dict['lod_score'] = f"{float(target_trait['lrs_score']) / 4.61:.1f}"
+ except:
+ results_dict['lod_score'] = "N/A"
+ results_dict['lrs_location'] = target_trait['lrs_location']
+ if bool(target_trait['additive']):
+ results_dict['additive'] = f"{float(target_trait['additive']):.3f}"
+ results_dict['lit_corr'] = "--"
+ results_dict['tissue_corr'] = "--"
+ results_dict['tissue_pvalue'] = "--"
+ if this_dataset['type'] == "ProbeSet":
+ if 'lit_corr' in trait:
+ results_dict['lit_corr'] = f"{float(trait['lit_corr']):.3f}"
+ if 'tissue_corr' in trait:
+ results_dict['tissue_corr'] = f"{float(trait['tissue_corr']):.3f}"
+ results_dict['tissue_pvalue'] = f"{float(trait['tissue_p_val']):.3e}"
+ elif target_dataset['type'] == "Publish":
+ results_dict['abbreviation_display'] = "N/A"
+ results_dict['description'] = "N/A"
+ results_dict['mean'] = "N/A"
+ results_dict['authors_display'] = "N/A"
+ results_dict['additive'] = "N/A"
+ results_dict['pubmed_link'] = "N/A"
+ results_dict['pubmed_text'] = "N/A"
+
+ if bool(target_trait['abbreviation']):
+ results_dict['abbreviation_display'] = target_trait['abbreviation']
+ if bool(target_trait['description']):
+ results_dict['description'] = target_trait['description']
+ if bool(target_trait['mean']):
+ results_dict['mean'] = f"{float(target_trait['mean']):.3f}"
+ if bool(target_trait['authors']):
+ authors_list = target_trait['authors'].split(',')
+ if len(authors_list) > 6:
+ results_dict['authors_display'] = ", ".join(
+ authors_list[:6]) + ", et al."
else:
- lit_corr_data[trait] = [gene_id, 0]
- else:
- lit_corr_data[trait] = [gene_id, 0]
-
- lit_corr_data = collections.OrderedDict(sorted(list(lit_corr_data.items()),
- key=lambda t: -abs(t[1][1])))
-
- return lit_corr_data
-
- def convert_to_mouse_gene_id(self, species=None, gene_id=None):
- """If the species is rat or human, translate the gene_id to the mouse geneid
-
- If there is no input gene_id or there's no corresponding mouse gene_id, return None
-
- """
- if not gene_id:
- return None
-
- mouse_gene_id = None
-
- if species == 'mouse':
- mouse_gene_id = gene_id
-
- elif species == 'rat':
-
- query = """SELECT mouse
- FROM GeneIDXRef
- WHERE rat='%s'""" % escape(gene_id)
-
- result = g.db.execute(query).fetchone()
- if result != None:
- mouse_gene_id = result.mouse
-
- elif species == 'human':
-
- query = """SELECT mouse
- FROM GeneIDXRef
- WHERE human='%s'""" % escape(gene_id)
-
- result = g.db.execute(query).fetchone()
- if result != None:
- mouse_gene_id = result.mouse
-
- return mouse_gene_id
-
- def get_sample_r_and_p_values(self, trait, target_samples):
- """Calculates the sample r (or rho) and p-value
-
- Given a primary trait and a target trait's sample values,
- calculates either the pearson r or spearman rho and the p-value
- using the corresponding scipy functions.
-
- """
-
- self.this_trait_vals = []
- target_vals = []
- for index, sample in enumerate(self.target_dataset.samplelist):
- if sample in self.sample_data:
- sample_value = self.sample_data[sample]
- target_sample_value = target_samples[index]
- 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)
-
- if num_overlap > 5:
- # ZS: 2015 could add biweight correlation, see http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3465711/
- # if self.corr_method == 'bicor':
- # sample_r, sample_p = do_bicor(
- # self.this_trait_vals, target_vals)
- if self.corr_method == 'pearson':
- sample_r, sample_p = scipy.stats.pearsonr(
- self.this_trait_vals, target_vals)
- else:
- sample_r, sample_p = scipy.stats.spearmanr(
- self.this_trait_vals, target_vals)
-
- if numpy.isnan(sample_r):
- pass
- else:
- self.correlation_data[trait] = [
- sample_r, sample_p, num_overlap]
-
- def process_samples(self, start_vars, sample_names, excluded_samples=None):
- if not excluded_samples:
- excluded_samples = ()
-
- sample_val_dict = json.loads(start_vars['sample_vals'])
- for sample in sample_names:
- if sample not in excluded_samples:
- value = sample_val_dict[sample]
- if not value.strip().lower() == 'x':
- self.sample_data[str(sample)] = float(value)
-
-
-# def do_bicor(this_trait_vals, target_trait_vals):
-# r_library = ro.r["library"] # Map the library function
-# r_options = ro.r["options"] # Map the options function
-
-# r_library("WGCNA")
-# r_bicor = ro.r["bicorAndPvalue"] # Map the bicorAndPvalue function
-
-# r_options(stringsAsFactors=False)
-
-# this_vals = ro.Vector(this_trait_vals)
-# target_vals = ro.Vector(target_trait_vals)
+ results_dict['authors_display'] = target_trait['authors']
+ if 'pubmed_id' in target_trait:
+ results_dict['pubmed_link'] = target_trait['pubmed_link']
+ results_dict['pubmed_text'] = target_trait['pubmed_text']
+ try:
+ results_dict['lod_score'] = f"{float(target_trait['lrs_score']) / 4.61:.1f}"
+ except:
+ results_dict['lod_score'] = "N/A"
+ results_dict['lrs_location'] = target_trait['lrs_location']
+ if bool(target_trait['additive']):
+ results_dict['additive'] = f"{float(target_trait['additive']):.3f}"
+ else:
+ results_dict['location'] = target_trait['location']
-# the_r, the_p, _fisher_transform, _the_t, _n_obs = [
-# numpy.asarray(x) for x in r_bicor(x=this_vals, y=target_vals)]
+ results_list.append(results_dict)
-# return the_r, the_p
+ return json.dumps(results_list)
def generate_corr_json(corr_results, this_trait, dataset, target_dataset, for_api=False):
@@ -598,6 +259,25 @@ def generate_corr_json(corr_results, this_trait, dataset, target_dataset, for_ap
return json.dumps(results_list)
+def get_formatted_corr_type(corr_type, corr_method):
+ formatted_corr_type = ""
+ if corr_type == "lit":
+ formatted_corr_type += "Literature Correlation "
+ elif corr_type == "tissue":
+ formatted_corr_type += "Tissue Correlation "
+ elif corr_type == "sample":
+ formatted_corr_type += "Genetic Correlation "
+
+ if corr_method == "pearson":
+ formatted_corr_type += "(Pearson's r)"
+ elif corr_method == "spearman":
+ formatted_corr_type += "(Spearman's rho)"
+ elif corr_method == "bicor":
+ formatted_corr_type += "(Biweight r)"
+
+ return formatted_corr_type
+
+
def get_header_fields(data_type, corr_method):
if data_type == "ProbeSet":
if corr_method == "spearman":
diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
index 9ac02ac5..e7b16e77 100644
--- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
+++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py
@@ -23,6 +23,9 @@ import math
import random
import string
+import rpy2.robjects as ro
+from rpy2.robjects.packages import importr
+
import numpy as np
import scipy
@@ -160,23 +163,22 @@ class CorrelationMatrix:
for sample in self.all_sample_list:
groups.append(1)
- # Not doing PCA until rpy2 is excised
self.pca_works = "False"
- # try:
- # corr_result_eigen = np.linalg.eig(np.array(self.pca_corr_results))
- # corr_eigen_value, corr_eigen_vectors = sortEigenVectors(
- # corr_result_eigen)
-
- # if self.do_PCA == True:
- # self.pca_works = "True"
- # self.pca_trait_ids = []
- # pca = self.calculate_pca(
- # list(range(len(self.traits))), corr_eigen_value, corr_eigen_vectors)
- # self.loadings_array = self.process_loadings()
- # else:
- # self.pca_works = "False"
- # except:
- # self.pca_works = "False"
+ try:
+ corr_result_eigen = np.linalg.eig(np.array(self.pca_corr_results))
+ corr_eigen_value, corr_eigen_vectors = sortEigenVectors(
+ corr_result_eigen)
+
+ if self.do_PCA == True:
+ self.pca_works = "True"
+ self.pca_trait_ids = []
+ pca = self.calculate_pca(
+ list(range(len(self.traits))), corr_eigen_value, corr_eigen_vectors)
+ self.loadings_array = self.process_loadings()
+ else:
+ self.pca_works = "False"
+ except:
+ self.pca_works = "False"
self.js_data = dict(traits=[trait.name for trait in self.traits],
groups=groups,
@@ -185,51 +187,51 @@ class CorrelationMatrix:
samples=self.all_sample_list,
sample_data=self.sample_data,)
- # def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors):
- # base = importr('base')
- # stats = importr('stats')
-
- # corr_results_to_list = robjects.FloatVector(
- # [item for sublist in self.pca_corr_results for item in sublist])
-
- # m = robjects.r.matrix(corr_results_to_list, nrow=len(cols))
- # eigen = base.eigen(m)
- # pca = stats.princomp(m, cor="TRUE")
- # self.loadings = pca.rx('loadings')
- # self.scores = pca.rx('scores')
- # self.scale = pca.rx('scale')
-
- # trait_array = zScore(self.trait_data_array)
- # trait_array_vectors = np.dot(corr_eigen_vectors, trait_array)
-
- # pca_traits = []
- # for i, vector in enumerate(trait_array_vectors):
- # # ZS: Check if below check is necessary
- # # if corr_eigen_value[i-1] > 100.0/len(self.trait_list):
- # pca_traits.append((vector * -1.0).tolist())
-
- # this_group_name = self.trait_list[0][1].group.name
- # temp_dataset = data_set.create_dataset(
- # dataset_name="Temp", dataset_type="Temp", group_name=this_group_name)
- # temp_dataset.group.get_samplelist()
- # for i, pca_trait in enumerate(pca_traits):
- # trait_id = "PCA" + str(i + 1) + "_" + temp_dataset.group.species + "_" + \
- # this_group_name + "_" + datetime.datetime.now().strftime("%m%d%H%M%S")
- # this_vals_string = ""
- # position = 0
- # for sample in temp_dataset.group.all_samples_ordered():
- # if sample in self.shared_samples_list:
- # this_vals_string += str(pca_trait[position])
- # this_vals_string += " "
- # position += 1
- # else:
- # this_vals_string += "x "
- # this_vals_string = this_vals_string[:-1]
-
- # Redis.set(trait_id, this_vals_string, ex=THIRTY_DAYS)
- # self.pca_trait_ids.append(trait_id)
-
- # return pca
+ def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors):
+ base = importr('base')
+ stats = importr('stats')
+
+ corr_results_to_list = ro.FloatVector(
+ [item for sublist in self.pca_corr_results for item in sublist])
+
+ m = ro.r.matrix(corr_results_to_list, nrow=len(cols))
+ eigen = base.eigen(m)
+ pca = stats.princomp(m, cor="TRUE")
+ self.loadings = pca.rx('loadings')
+ self.scores = pca.rx('scores')
+ self.scale = pca.rx('scale')
+
+ trait_array = zScore(self.trait_data_array)
+ trait_array_vectors = np.dot(corr_eigen_vectors, trait_array)
+
+ pca_traits = []
+ for i, vector in enumerate(trait_array_vectors):
+ # ZS: Check if below check is necessary
+ # if corr_eigen_value[i-1] > 100.0/len(self.trait_list):
+ pca_traits.append((vector * -1.0).tolist())
+
+ this_group_name = self.trait_list[0][1].group.name
+ temp_dataset = data_set.create_dataset(
+ dataset_name="Temp", dataset_type="Temp", group_name=this_group_name)
+ temp_dataset.group.get_samplelist()
+ for i, pca_trait in enumerate(pca_traits):
+ trait_id = "PCA" + str(i + 1) + "_" + temp_dataset.group.species + "_" + \
+ this_group_name + "_" + datetime.datetime.now().strftime("%m%d%H%M%S")
+ this_vals_string = ""
+ position = 0
+ for sample in temp_dataset.group.all_samples_ordered():
+ if sample in self.shared_samples_list:
+ this_vals_string += str(pca_trait[position])
+ this_vals_string += " "
+ position += 1
+ else:
+ this_vals_string += "x "
+ this_vals_string = this_vals_string[:-1]
+
+ Redis.set(trait_id, this_vals_string, ex=THIRTY_DAYS)
+ self.pca_trait_ids.append(trait_id)
+
+ return pca
def process_loadings(self):
loadings_array = []
diff --git a/wqflask/wqflask/decorators.py b/wqflask/wqflask/decorators.py
index f0978fd3..54aa6795 100644
--- a/wqflask/wqflask/decorators.py
+++ b/wqflask/wqflask/decorators.py
@@ -1,14 +1,36 @@
"""This module contains gn2 decorators"""
from flask import g
+from typing import Dict
from functools import wraps
+from utility.hmac import hmac_creation
+import json
+import requests
-def admin_login_required(f):
+
+def edit_access_required(f):
"""Use this for endpoints where admins are required"""
@wraps(f)
def wrap(*args, **kwargs):
- if g.user_session.record.get(b"user_email_address") not in [
- b"labwilliams@gmail.com"]:
+ resource_id: str = ""
+ if kwargs.get("inbredset_id"): # data type: dataset-publish
+ resource_id = hmac_creation("dataset-publish:"
+ f"{kwargs.get('inbredset_id')}:"
+ f"{kwargs.get('name')}")
+ if kwargs.get("dataset_name"): # data type: dataset-probe
+ resource_id = hmac_creation("dataset-probeset:"
+ f"{kwargs.get('dataset_name')}")
+ response: Dict = {}
+ try:
+ _user_id = g.user_session.record.get(b"user_id",
+ "").decode("utf-8")
+ response = json.loads(
+ requests.get("http://localhost:8080/"
+ "available?resource="
+ f"{resource_id}&user={_user_id}").content)
+ except:
+ response = {}
+ if "edit" not in response.get("data", []):
return "You need to be admin", 401
return f(*args, **kwargs)
return wrap
diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py
index ec17d3b0..6254b9b9 100644
--- a/wqflask/wqflask/marker_regression/display_mapping_results.py
+++ b/wqflask/wqflask/marker_regression/display_mapping_results.py
@@ -24,6 +24,7 @@
#
# Last updated by Zach 12/14/2010
+import datetime
import string
from math import *
from PIL import Image
@@ -271,6 +272,7 @@ class DisplayMappingResults:
# Needing for form submission when doing single chr
# mapping or remapping after changing options
self.sample_vals = start_vars['sample_vals']
+ self.vals_hash= start_vars['vals_hash']
self.sample_vals_dict = json.loads(self.sample_vals)
self.transform = start_vars['transform']
@@ -355,8 +357,7 @@ class DisplayMappingResults:
if 'use_loco' in list(start_vars.keys()) and self.mapping_method == "gemma":
self.use_loco = start_vars['use_loco']
- if 'reaper_version' in list(start_vars.keys()) and self.mapping_method == "reaper":
- self.reaper_version = start_vars['reaper_version']
+ if self.mapping_method == "reaper":
if 'output_files' in start_vars:
self.output_files = ",".join(
[(the_file if the_file is not None else "") for the_file in start_vars['output_files']])
@@ -651,7 +652,7 @@ class DisplayMappingResults:
btminfo.append(
'Mapping using genotype data as a trait will result in infinity LRS at one locus. In order to display the result properly, all LRSs higher than 100 are capped at 100.')
- def plotIntMapping(self, canvas, offset=(80, 120, 90, 100), zoom=1, startMb=None, endMb=None, showLocusForm=""):
+ def plotIntMapping(self, canvas, offset=(80, 120, 110, 100), zoom=1, startMb=None, endMb=None, showLocusForm=""):
im_drawer = ImageDraw.Draw(canvas)
# calculating margins
xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
@@ -661,7 +662,7 @@ class DisplayMappingResults:
if self.legendChecked:
yTopOffset += 10
if self.covariates != "" and self.controlLocus and self.doControl != "false":
- yTopOffset += 20
+ yTopOffset += 25
if len(self.transform) > 0:
yTopOffset += 5
else:
@@ -861,6 +862,9 @@ class DisplayMappingResults:
(item[1], yZero - item[2] * bootHeightThresh / maxBootCount)),
fill=self.BOOTSTRAP_BOX_COLOR, outline=BLACK)
+ if maxBootCount == 0:
+ return
+
# draw boot scale
highestPercent = (maxBootCount * 100.0) / nboot
bootScale = Plot.detScale(0, highestPercent)
@@ -1192,43 +1196,47 @@ class DisplayMappingResults:
dataset_label = "%s - %s" % (self.dataset.group.name,
self.dataset.fullname)
- string1 = 'Dataset: %s' % (dataset_label)
+
+ self.current_datetime = datetime.datetime.now().strftime("%b %d %Y %H:%M:%S")
+ string1 = 'UTC Timestamp: %s' % (self.current_datetime)
+ string2 = 'Dataset: %s' % (dataset_label)
+ string3 = 'Trait Hash: %s' % (self.vals_hash)
if self.genofile_string == "":
- string2 = 'Genotype File: %s.geno' % self.dataset.group.name
+ string4 = 'Genotype File: %s.geno' % self.dataset.group.name
else:
- string2 = 'Genotype File: %s' % self.genofile_string
+ string4 = 'Genotype File: %s' % self.genofile_string.split(":")[1]
- string4 = ''
+ string6 = ''
if self.mapping_method == "gemma" or self.mapping_method == "gemma_bimbam":
if self.use_loco == "True":
- string3 = 'Using GEMMA mapping method with LOCO and '
+ string5 = 'Using GEMMA mapping method with LOCO and '
else:
- string3 = 'Using GEMMA mapping method with '
+ string5 = 'Using GEMMA mapping method with '
if self.covariates != "":
- string3 += 'the cofactors below:'
+ string5 += 'the cofactors below:'
cofactor_names = ", ".join(
[covar.split(":")[0] for covar in self.covariates.split(",")])
- string4 = cofactor_names
+ string6 = cofactor_names
else:
- string3 += 'no cofactors'
+ string5 += 'no cofactors'
elif self.mapping_method == "rqtl_plink" or self.mapping_method == "rqtl_geno":
- string3 = 'Using R/qtl mapping method with '
+ string5 = 'Using R/qtl mapping method with '
if self.covariates != "":
- string3 += 'the cofactors below:'
+ string5 += 'the cofactors below:'
cofactor_names = ", ".join(
[covar.split(":")[0] for covar in self.covariates.split(",")])
- string4 = cofactor_names
+ string6 = cofactor_names
elif self.controlLocus and self.doControl != "false":
- string3 += '%s as control' % self.controlLocus
+ string5 += '%s as control' % self.controlLocus
else:
- string3 += 'no cofactors'
+ string5 += 'no cofactors'
else:
- string3 = 'Using Haldane mapping function with '
+ string5 = 'Using Haldane mapping function with '
if self.controlLocus and self.doControl != "false":
- string3 += '%s as control' % self.controlLocus
+ string5 += '%s as control' % self.controlLocus
else:
- string3 += 'no control for other QTLs'
+ string5 += 'no control for other QTLs'
y_constant = 10
if self.this_trait.name:
@@ -1240,24 +1248,26 @@ class DisplayMappingResults:
if self.this_trait.symbol:
identification += "Trait: %s - %s" % (
- self.this_trait.name, self.this_trait.symbol)
+ self.this_trait.display_name, self.this_trait.symbol)
elif self.dataset.type == "Publish":
if self.this_trait.post_publication_abbreviation:
identification += "Trait: %s - %s" % (
- self.this_trait.name, self.this_trait.post_publication_abbreviation)
+ self.this_trait.display_name, self.this_trait.post_publication_abbreviation)
elif self.this_trait.pre_publication_abbreviation:
identification += "Trait: %s - %s" % (
- self.this_trait.name, self.this_trait.pre_publication_abbreviation)
+ self.this_trait.display_name, self.this_trait.pre_publication_abbreviation)
else:
- identification += "Trait: %s" % (self.this_trait.name)
+ identification += "Trait: %s" % (self.this_trait.display_name)
else:
- identification += "Trait: %s" % (self.this_trait.name)
+ identification += "Trait: %s" % (self.this_trait.display_name)
identification += " with %s samples" % (self.n_samples)
d = 4 + max(
im_drawer.textsize(identification, font=labelFont)[0],
im_drawer.textsize(string1, font=labelFont)[0],
- im_drawer.textsize(string2, font=labelFont)[0])
+ im_drawer.textsize(string2, font=labelFont)[0],
+ im_drawer.textsize(string3, font=labelFont)[0],
+ im_drawer.textsize(string4, font=labelFont)[0])
im_drawer.text(
text=identification,
xy=(xLeftOffset, y_constant * fontZoom), font=labelFont,
@@ -1266,7 +1276,9 @@ class DisplayMappingResults:
else:
d = 4 + max(
im_drawer.textsize(string1, font=labelFont)[0],
- im_drawer.textsize(string2, font=labelFont)[0])
+ im_drawer.textsize(string2, font=labelFont)[0],
+ im_drawer.textsize(string3, font=labelFont)[0],
+ im_drawer.textsize(string4, font=labelFont)[0])
if len(self.transform) > 0:
transform_text = "Transform - "
@@ -1293,14 +1305,22 @@ class DisplayMappingResults:
text=string2, xy=(xLeftOffset, y_constant * fontZoom),
font=labelFont, fill=labelColor)
y_constant += 15
- if string3 != '':
+ im_drawer.text(
+ text=string3, xy=(xLeftOffset, y_constant * fontZoom),
+ font=labelFont, fill=labelColor)
+ y_constant += 15
+ im_drawer.text(
+ text=string4, xy=(xLeftOffset, y_constant * fontZoom),
+ font=labelFont, fill=labelColor)
+ y_constant += 15
+ if string4 != '':
im_drawer.text(
- text=string3, xy=(xLeftOffset, y_constant * fontZoom),
+ text=string5, xy=(xLeftOffset, y_constant * fontZoom),
font=labelFont, fill=labelColor)
y_constant += 15
- if string4 != '':
+ if string5 != '':
im_drawer.text(
- text=string4, xy=(xLeftOffset, y_constant * fontZoom),
+ text=string6, xy=(xLeftOffset, y_constant * fontZoom),
font=labelFont, fill=labelColor)
def drawGeneBand(self, canvas, gifmap, plotXScale, offset=(40, 120, 80, 10), zoom=1, startMb=None, endMb=None):
@@ -2110,7 +2130,7 @@ class DisplayMappingResults:
thisChr.append(
[_locus.name, _locus.cM - Locus0CM])
else:
- for j in (0, nLoci / 4, nLoci / 2, nLoci * 3 / 4, -1):
+ for j in (0, round(nLoci / 4), round(nLoci / 2), round(nLoci * 3 / 4), -1):
while _chr[j].name == ' - ':
j += 1
if _chr[j].cM != preLpos:
@@ -2286,20 +2306,9 @@ class DisplayMappingResults:
font=VERDANA_FILE, size=int(18 * zoom * 1.5))
yZero = yTopOffset + plotHeight
- # LRSHeightThresh = drawAreaHeight
- # AdditiveHeightThresh = drawAreaHeight/2
- # DominanceHeightThresh = drawAreaHeight/2
- if self.selectedChr == 1:
- LRSHeightThresh = drawAreaHeight - yTopOffset + 30 * (zoom - 1)
- AdditiveHeightThresh = LRSHeightThresh / 2
- DominanceHeightThresh = LRSHeightThresh / 2
- else:
- LRSHeightThresh = drawAreaHeight
- AdditiveHeightThresh = drawAreaHeight / 2
- DominanceHeightThresh = drawAreaHeight / 2
- # LRSHeightThresh = (yZero - yTopOffset + 30*(zoom - 1))
- # AdditiveHeightThresh = LRSHeightThresh/2
- # DominanceHeightThresh = LRSHeightThresh/2
+ LRSHeightThresh = drawAreaHeight
+ AdditiveHeightThresh = drawAreaHeight / 2
+ DominanceHeightThresh = drawAreaHeight / 2
if LRS_LOD_Max > 100:
LRSScale = 20.0
@@ -2380,8 +2389,7 @@ class DisplayMappingResults:
# ZS: I don't know if what I did here with this inner function is clever or overly complicated, but it's the only way I could think of to avoid duplicating the code inside this function
def add_suggestive_significant_lines_and_legend(start_pos_x, chr_length_dist):
- rightEdge = int(start_pos_x + chr_length_dist * \
- plotXScale - self.SUGGESTIVE_WIDTH / 1.5)
+ rightEdge = xLeftOffset + plotWidth
im_drawer.line(
xy=((start_pos_x + self.SUGGESTIVE_WIDTH / 1.5, suggestiveY),
(rightEdge, suggestiveY)),
@@ -2569,7 +2577,10 @@ class DisplayMappingResults:
Xc = startPosX + ((qtlresult['Mb'] - start_cm - startMb) * plotXScale) * (
((qtlresult['Mb'] - start_cm - startMb) * plotXScale) / ((qtlresult['Mb'] - start_cm - startMb + self.GraphInterval) * plotXScale))
else:
- Xc = startPosX + (qtlresult['Mb'] - startMb) * plotXScale
+ if self.selectedChr != -1 and qtlresult['Mb'] > endMb:
+ Xc = startPosX + endMb * plotXScale
+ else:
+ Xc = startPosX + (qtlresult['Mb'] - startMb) * plotXScale
# updated by NL 06-18-2011:
# fix the over limit LRS graph issue since genotype trait may give infinite LRS;
@@ -2580,36 +2591,29 @@ class DisplayMappingResults:
if 'lrs_value' in qtlresult:
if self.LRS_LOD == "LOD" or self.LRS_LOD == "-logP":
if qtlresult['lrs_value'] > 460 or qtlresult['lrs_value'] == 'inf':
- #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/(LRSAxisList[-1]*self.LODFACTOR)
Yc = yZero - webqtlConfig.MAXLRS * \
LRSHeightThresh / \
(LRS_LOD_Max * self.LODFACTOR)
else:
- #Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/(LRSAxisList[-1]*self.LODFACTOR)
Yc = yZero - \
qtlresult['lrs_value'] * LRSHeightThresh / \
(LRS_LOD_Max * self.LODFACTOR)
else:
if qtlresult['lrs_value'] > 460 or qtlresult['lrs_value'] == 'inf':
- #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSAxisList[-1]
Yc = yZero - webqtlConfig.MAXLRS * LRSHeightThresh / LRS_LOD_Max
else:
- #Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/LRSAxisList[-1]
Yc = yZero - \
qtlresult['lrs_value'] * \
LRSHeightThresh / LRS_LOD_Max
else:
if qtlresult['lod_score'] > 100 or qtlresult['lod_score'] == 'inf':
- #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSAxisList[-1]
Yc = yZero - webqtlConfig.MAXLRS * LRSHeightThresh / LRS_LOD_Max
else:
if self.LRS_LOD == "LRS":
- #Yc = yZero - qtlresult['lod_score']*self.LODFACTOR*LRSHeightThresh/LRSAxisList[-1]
Yc = yZero - \
qtlresult['lod_score'] * self.LODFACTOR * \
LRSHeightThresh / LRS_LOD_Max
else:
- #Yc = yZero - qtlresult['lod_score']*LRSHeightThresh/LRSAxisList[-1]
Yc = yZero - \
qtlresult['lod_score'] * \
LRSHeightThresh / LRS_LOD_Max
@@ -2642,14 +2646,12 @@ class DisplayMappingResults:
AdditiveHeightThresh / additiveMax
AdditiveCoordXY.append((Xc, Yc))
+ if self.selectedChr != -1 and qtlresult['Mb'] > endMb:
+ break
+
m += 1
if self.manhattan_plot != True:
- # im_drawer.polygon(
- # xy=LRSCoordXY,
- # outline=thisLRSColor
- # #, closed=0, edgeWidth=lrsEdgeWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)
- # )
draw_open_polygon(canvas, xy=LRSCoordXY, outline=thisLRSColor,
width=lrsEdgeWidth)
diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py
index f88c5ac8..623ab87f 100644
--- a/wqflask/wqflask/marker_regression/gemma_mapping.py
+++ b/wqflask/wqflask/marker_regression/gemma_mapping.py
@@ -11,6 +11,7 @@ from utility.tools import flat_files
from utility.tools import GEMMA_WRAPPER_COMMAND
from utility.tools import TEMPDIR
from utility.tools import WEBSERVER_MODE
+from gn3.computations.gemma import generate_hash_of_string
import utility.logger
logger = utility.logger.getLogger(__name__)
@@ -34,10 +35,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
genofile_name = this_dataset.group.name
if first_run:
- trait_filename = (f"{str(this_dataset.group.name)}_"
- f"{str(this_trait.name)}_"
- f"{generate_random_n_string(6)}")
- gen_pheno_txt_file(this_dataset, genofile_name, vals, trait_filename)
+ pheno_filename = gen_pheno_txt_file(this_dataset, genofile_name, vals)
if not os.path.isfile(f"{webqtlConfig.GENERATED_IMAGE_DIR}"
f"{genofile_name}_output.assoc.txt"):
@@ -56,13 +54,13 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
chr_list_string = ",".join(this_chromosomes_name)
if covariates != "":
- gen_covariates_file(this_dataset, covariates, samples)
+ covar_filename = gen_covariates_file(this_dataset, covariates, samples)
if use_loco == "True":
generate_k_command = (f"{GEMMA_WRAPPER_COMMAND} --json --loco "
f"{chr_list_string} -- {GEMMAOPTS} "
f"-g {flat_files('genotype/bimbam')}/"
f"{genofile_name}_geno.txt -p "
- f"{TEMPDIR}/gn2/{trait_filename}.txt -a "
+ f"{TEMPDIR}/gn2/{pheno_filename}.txt -a "
f"{flat_files('genotype/bimbam')}/"
f"{genofile_name}_snps.txt -gk > "
f"{TEMPDIR}/gn2/{k_output_filename}.json")
@@ -73,10 +71,10 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
f"-- {GEMMAOPTS} "
f"-g {flat_files('genotype/bimbam')}/"
f"{genofile_name}_geno.txt "
- f"-p {TEMPDIR}/gn2/{trait_filename}.txt ")
+ f"-p {TEMPDIR}/gn2/{pheno_filename}.txt ")
if covariates != "":
gemma_command += (f"-c {flat_files('mapping')}/"
- f"{this_dataset.group.name}_covariates.txt "
+ f"{covar_filename}.txt "
f"-a {flat_files('genotype/bimbam')}/"
f"{genofile_name}_snps.txt "
f"-lmm 9 -maf {maf} > {TEMPDIR}/gn2/"
@@ -92,7 +90,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
f"{GEMMAOPTS} "
f" -g {flat_files('genotype/bimbam')}/"
f"{genofile_name}_geno.txt -p "
- f"{TEMPDIR}/gn2/{trait_filename}.txt -a "
+ f"{TEMPDIR}/gn2/{pheno_filename}.txt -a "
f"{flat_files('genotype/bimbam')}/"
f"{genofile_name}_snps.txt -gk > "
f"{TEMPDIR}/gn2/{k_output_filename}.json")
@@ -106,12 +104,11 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
f"{genofile_name}_snps.txt "
f"-lmm 9 -g {flat_files('genotype/bimbam')}/"
f"{genofile_name}_geno.txt -p "
- f"{TEMPDIR}/gn2/{trait_filename}.txt ")
+ f"{TEMPDIR}/gn2/{pheno_filename}.txt ")
if covariates != "":
gemma_command += (f" -c {flat_files('mapping')}/"
- f"{this_dataset.group.name}"
- f"_covariates.txt > "
+ f"{covar_filename}.txt > "
f"{TEMPDIR}/gn2/{gwa_output_filename}.json")
else:
gemma_command += f" > {TEMPDIR}/gn2/{gwa_output_filename}.json"
@@ -129,16 +126,20 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco,
return marker_obs, gwa_output_filename
-def gen_pheno_txt_file(this_dataset, genofile_name, vals, trait_filename):
+def gen_pheno_txt_file(this_dataset, genofile_name, vals):
"""Generates phenotype file for GEMMA"""
- with open(f"{TEMPDIR}/gn2/{trait_filename}.txt", "w") as outfile:
+ filename = "PHENO_" + generate_hash_of_string(this_dataset.name + str(vals)).replace("/", "_")
+
+ with open(f"{TEMPDIR}/gn2/{filename}.txt", "w") as outfile:
for value in vals:
if value == "x":
outfile.write("NA\n")
else:
outfile.write(value + "\n")
+ return filename
+
def gen_covariates_file(this_dataset, covariates, samples):
covariate_list = covariates.split(",")
@@ -168,14 +169,18 @@ def gen_covariates_file(this_dataset, covariates, samples):
this_covariate_data.append("-9")
covariate_data_object.append(this_covariate_data)
+ filename = "COVAR_" + generate_hash_of_string(this_dataset.name + str(covariate_data_object)).replace("/", "_")
+
with open((f"{flat_files('mapping')}/"
- f"{this_dataset.group.name}_covariates.txt"),
+ f"{filename}.txt"),
"w") as outfile:
for i in range(len(covariate_data_object[0])):
for this_covariate in covariate_data_object:
outfile.write(str(this_covariate[i]) + "\t")
outfile.write("\n")
+ return filename
+
def parse_loco_output(this_dataset, gwa_output_filename, loco="True"):
diff --git a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
index 4d6715ba..801674e1 100644
--- a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
+++ b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py
@@ -178,101 +178,6 @@ def parse_reaper_output(gwa_filename, permu_filename, bootstrap_filename):
return marker_obs, permu_vals, bootstrap_vals
-def run_original_reaper(this_trait, dataset, samples_before, trait_vals, json_data, num_perm, bootCheck, num_bootstrap, do_control, control_marker, manhattan_plot):
- genotype = dataset.group.read_genotype_file(use_reaper=True)
-
- if manhattan_plot != True:
- genotype = genotype.addinterval()
-
- trimmed_samples = []
- trimmed_values = []
- for i in range(0, len(samples_before)):
- try:
- trimmed_values.append(float(trait_vals[i]))
- trimmed_samples.append(str(samples_before[i]))
- except:
- pass
-
- perm_output = []
- bootstrap_results = []
-
- if num_perm < 100:
- suggestive = 0
- significant = 0
- else:
- perm_output = genotype.permutation(
- strains=trimmed_samples, trait=trimmed_values, nperm=num_perm)
- suggestive = perm_output[int(num_perm * 0.37 - 1)]
- significant = perm_output[int(num_perm * 0.95 - 1)]
- # highly_significant = perm_output[int(num_perm*0.99-1)] #ZS: Currently not used, but leaving it here just in case
-
- json_data['suggestive'] = suggestive
- json_data['significant'] = significant
-
- if control_marker != "" and do_control == "true":
- reaper_results = genotype.regression(strains=trimmed_samples,
- trait=trimmed_values,
- control=str(control_marker))
- if bootCheck:
- control_geno = []
- control_geno2 = []
- _FIND = 0
- for _chr in genotype:
- for _locus in _chr:
- if _locus.name == control_marker:
- control_geno2 = _locus.genotype
- _FIND = 1
- break
- if _FIND:
- break
- if control_geno2:
- _prgy = list(genotype.prgy)
- for _strain in trimmed_samples:
- _idx = _prgy.index(_strain)
- control_geno.append(control_geno2[_idx])
-
- bootstrap_results = genotype.bootstrap(strains=trimmed_samples,
- trait=trimmed_values,
- control=control_geno,
- nboot=num_bootstrap)
- else:
- reaper_results = genotype.regression(strains=trimmed_samples,
- trait=trimmed_values)
-
- if bootCheck:
- bootstrap_results = genotype.bootstrap(strains=trimmed_samples,
- trait=trimmed_values,
- nboot=num_bootstrap)
-
- json_data['chr'] = []
- json_data['pos'] = []
- json_data['lod.hk'] = []
- json_data['markernames'] = []
- # if self.additive:
- # self.json_data['additive'] = []
-
- # Need to convert the QTL objects that qtl reaper returns into a json serializable dictionary
- qtl_results = []
- for qtl in reaper_results:
- reaper_locus = qtl.locus
- # ZS: Convert chr to int
- converted_chr = reaper_locus.chr
- if reaper_locus.chr != "X" and reaper_locus.chr != "X/Y":
- converted_chr = int(reaper_locus.chr)
- json_data['chr'].append(converted_chr)
- json_data['pos'].append(reaper_locus.Mb)
- json_data['lod.hk'].append(qtl.lrs)
- json_data['markernames'].append(reaper_locus.name)
- # if self.additive:
- # self.json_data['additive'].append(qtl.additive)
- locus = {"name": reaper_locus.name, "chr": reaper_locus.chr,
- "cM": reaper_locus.cM, "Mb": reaper_locus.Mb}
- qtl = {"lrs_value": qtl.lrs, "chr": converted_chr, "Mb": reaper_locus.Mb,
- "cM": reaper_locus.cM, "name": reaper_locus.name, "additive": qtl.additive, "dominance": qtl.dominance}
- qtl_results.append(qtl)
- return qtl_results, json_data, perm_output, suggestive, significant, bootstrap_results
-
-
def natural_sort(marker_list):
"""
Function to naturally sort numbers + strings, adopted from user Mark Byers here: https://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort
diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py
index 09afb8d1..1dca1b1b 100644
--- a/wqflask/wqflask/marker_regression/rqtl_mapping.py
+++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py
@@ -39,7 +39,7 @@ def run_rqtl(trait_name, vals, samples, dataset, mapping_scale, model, method, n
}
if do_control == "true" and control_marker:
- post_data["control_marker"] = control_marker
+ post_data["control"] = control_marker
if not manhattan_plot:
post_data["interval"] = True
@@ -61,6 +61,7 @@ def get_hash_of_textio(the_file: TextIO) -> str:
the_file.seek(0)
hash_of_file = hashlib.md5(the_file.read().encode()).hexdigest()
+ hash_of_file = hash_of_file.replace("/", "_") # Replace / with _ to prevent issue with filenames being translated to directories
return hash_of_file
@@ -89,7 +90,7 @@ def write_phenotype_file(trait_name: str,
for i, sample in enumerate(samples):
this_row = [sample]
if vals[i] != "x":
- this_row.append(vals[i])
+ this_row.append(str(round(float(vals[i]), 3)))
else:
this_row.append("NA")
for cofactor in cofactor_data:
@@ -126,7 +127,7 @@ def cofactors_to_dict(cofactors: str, dataset_ob, samples) -> Dict:
sample_data = trait_ob.data
for index, sample in enumerate(samples):
if sample in sample_data:
- sample_value = sample_data[sample].value
+ sample_value = str(round(float(sample_data[sample].value), 3))
cofactor_dict[cofactor_name].append(sample_value)
else:
cofactor_dict[cofactor_name].append("NA")
diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py
index c5b980a7..290c4a14 100644
--- a/wqflask/wqflask/marker_regression/run_mapping.py
+++ b/wqflask/wqflask/marker_regression/run_mapping.py
@@ -75,6 +75,7 @@ class RunMapping:
self.vals = []
self.samples = []
self.sample_vals = start_vars['sample_vals']
+ self.vals_hash = start_vars['vals_hash']
sample_val_dict = json.loads(self.sample_vals)
samples = sample_val_dict.keys()
if (len(genofile_samplelist) != 0):
@@ -103,9 +104,7 @@ class RunMapping:
if "results_path" in start_vars:
self.mapping_results_path = start_vars['results_path']
else:
- mapping_results_filename = self.dataset.group.name + "_" + \
- ''.join(random.choice(string.ascii_uppercase + string.digits)
- for _ in range(6))
+ mapping_results_filename = "_".join([self.dataset.group.name, self.vals_hash]).replace("/", "_")
self.mapping_results_path = "{}{}.csv".format(
webqtlConfig.GENERATED_IMAGE_DIR, mapping_results_filename)
@@ -220,7 +219,7 @@ class RunMapping:
elif self.mapping_method == "rqtl_plink":
results = self.run_rqtl_plink()
elif self.mapping_method == "rqtl_geno":
- perm_strata = []
+ self.perm_strata = []
if "perm_strata" in start_vars and "categorical_vars" in start_vars:
self.categorical_vars = start_vars["categorical_vars"].split(
",")
@@ -229,7 +228,7 @@ class RunMapping:
sample_names=self.samples,
this_trait=self.this_trait)
- perm_strata = get_perm_strata(
+ self.perm_strata = get_perm_strata(
self.this_trait, primary_samples, self.categorical_vars, self.samples)
self.score_type = "LOD"
self.control_marker = start_vars['control_marker']
@@ -243,10 +242,10 @@ class RunMapping:
# self.pair_scan = True
if self.permCheck and self.num_perm > 0:
self.perm_output, self.suggestive, self.significant, results = rqtl_mapping.run_rqtl(
- self.this_trait.name, self.vals, self.samples, self.dataset, self.mapping_scale, self.model, self.method, self.num_perm, perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
+ self.this_trait.name, self.vals, self.samples, self.dataset, self.mapping_scale, self.model, self.method, self.num_perm, self.perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
else:
results = rqtl_mapping.run_rqtl(self.this_trait.name, self.vals, self.samples, self.dataset, self.mapping_scale, self.model, self.method,
- self.num_perm, perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
+ self.num_perm, self.perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
elif self.mapping_method == "reaper":
if "startMb" in start_vars: # ZS: Check if first time page loaded, so it can default to ON
if "additiveCheck" in start_vars:
@@ -272,47 +271,32 @@ class RunMapping:
self.bootCheck = False
self.num_bootstrap = 0
- self.reaper_version = start_vars['reaper_version']
-
self.control_marker = start_vars['control_marker']
self.do_control = start_vars['do_control']
logger.info("Running qtlreaper")
- if self.reaper_version == "new":
- self.first_run = True
- self.output_files = None
- # ZS: check if first run so existing result files can be used if it isn't (for example zooming on a chromosome, etc)
- if 'first_run' in start_vars:
- self.first_run = False
- if 'output_files' in start_vars:
- self.output_files = start_vars['output_files'].split(
- ",")
-
- results, self.perm_output, self.suggestive, self.significant, self.bootstrap_results, self.output_files = qtlreaper_mapping.run_reaper(self.this_trait,
- self.dataset,
- self.samples,
- self.vals,
- self.json_data,
- self.num_perm,
- self.bootCheck,
- self.num_bootstrap,
- self.do_control,
- self.control_marker,
- self.manhattan_plot,
- self.first_run,
- self.output_files)
- else:
- results, self.json_data, self.perm_output, self.suggestive, self.significant, self.bootstrap_results = qtlreaper_mapping.run_original_reaper(self.this_trait,
- self.dataset,
- self.samples,
- self.vals,
- self.json_data,
- self.num_perm,
- self.bootCheck,
- self.num_bootstrap,
- self.do_control,
- self.control_marker,
- self.manhattan_plot)
+ self.first_run = True
+ self.output_files = None
+ # ZS: check if first run so existing result files can be used if it isn't (for example zooming on a chromosome, etc)
+ if 'first_run' in start_vars:
+ self.first_run = False
+ if 'output_files' in start_vars:
+ self.output_files = start_vars['output_files'].split(
+ ",")
+
+ results, self.perm_output, self.suggestive, self.significant, self.bootstrap_results, self.output_files = qtlreaper_mapping.run_reaper(self.this_trait,
+ self.dataset,
+ self.samples,
+ self.vals,
+ self.json_data,
+ self.num_perm,
+ self.bootCheck,
+ self.num_bootstrap,
+ self.do_control,
+ self.control_marker,
+ self.manhattan_plot,
+ self.first_run,
+ self.output_files)
elif self.mapping_method == "plink":
self.score_type = "-logP"
self.manhattan_plot = True
@@ -421,8 +405,9 @@ class RunMapping:
total_markers = len(self.qtl_results)
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, self.transform, self.covariates, self.n_samples)
+ export_mapping_results(self.dataset, self.this_trait, self.qtl_results,
+ self.mapping_results_path, self.mapping_scale, self.score_type,
+ self.transform, self.covariates, self.n_samples, self.vals_hash)
with Bench("Trimming Markers for Figure"):
if len(self.qtl_results) > 30000:
@@ -540,13 +525,15 @@ class RunMapping:
return trimmed_genotype_data
-def export_mapping_results(dataset, trait, markers, results_path, mapping_scale, score_type, transform, covariates, n_samples):
+def export_mapping_results(dataset, trait, markers, results_path, mapping_scale, score_type, transform, covariates, n_samples, vals_hash):
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")
+ output_file.write("Trait: " + trait.display_name + "\n")
+ output_file.write("Trait Hash: " + vals_hash + "\n")
output_file.write("N Samples: " + str(n_samples) + "\n")
if len(transform) > 0:
transform_text = "Transform - "
@@ -673,9 +660,9 @@ def trim_markers_for_table(markers):
sorted_markers = sorted(
markers, key=lambda k: k['lrs_value'], reverse=True)
- # ZS: So we end up with a list of just 2000 markers
- if len(sorted_markers) >= 2000:
- trimmed_sorted_markers = sorted_markers[:2000]
+ #ZS: So we end up with a list of just 2000 markers
+ if len(sorted_markers) >= 10000:
+ trimmed_sorted_markers = sorted_markers[:10000]
return trimmed_sorted_markers
else:
return sorted_markers
@@ -765,9 +752,9 @@ def get_perm_strata(this_trait, sample_list, categorical_vars, used_samples):
if sample in list(sample_list.sample_attribute_values.keys()):
combined_string = ""
for var in categorical_vars:
- if var.lower() in sample_list.sample_attribute_values[sample]:
+ if var in sample_list.sample_attribute_values[sample]:
combined_string += str(
- sample_list.sample_attribute_values[sample][var.lower()])
+ sample_list.sample_attribute_values[sample][var])
else:
combined_string += "NA"
else:
diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py
index b28c1b04..c54dd0b3 100644
--- a/wqflask/wqflask/resource_manager.py
+++ b/wqflask/wqflask/resource_manager.py
@@ -8,8 +8,6 @@ from wqflask import app
from utility.authentication_tools import check_owner_or_admin
from utility.redis_tools import get_resource_info, get_group_info, get_groups_like_unique_column, get_user_id, get_user_by_unique_column, get_users_like_unique_column, add_access_mask, add_resource, change_resource_owner
-from utility.logger import getLogger
-logger = getLogger(__name__)
@app.route("/resources/manage", methods=('GET', 'POST'))
diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py
index 92cea550..ae30aa59 100644
--- a/wqflask/wqflask/show_trait/SampleList.py
+++ b/wqflask/wqflask/show_trait/SampleList.py
@@ -32,7 +32,7 @@ class SampleList:
for counter, sample_name in enumerate(sample_names, 1):
sample_name = sample_name.replace("_2nd_", "")
- # ZS: self.this_trait will be a list if it is a Temp trait
+ # self.this_trait will be a list if it is a Temp trait
if isinstance(self.this_trait, list):
sample = webqtlCaseData.webqtlCaseData(name=sample_name)
if counter <= len(self.this_trait):
@@ -47,7 +47,7 @@ class SampleList:
name=sample_name,
value=float(self.this_trait[counter - 1]))
else:
- # ZS - If there's no value for the sample/strain,
+ # If there's no value for the sample/strain,
# create the sample object (so samples with no value
# are still displayed in the table)
try:
@@ -63,29 +63,29 @@ class SampleList:
sample.this_id = str(counter)
- # ZS: For extra attribute columns; currently only used by
+ # For extra attribute columns; currently only used by
# several datasets
if self.sample_attribute_values:
sample.extra_attributes = self.sample_attribute_values.get(
sample_name, {})
- # ZS: Add a url so RRID case attributes can be displayed as links
- if 'rrid' in sample.extra_attributes:
+ # Add a url so RRID case attributes can be displayed as links
+ if '36' in sample.extra_attributes:
if self.dataset.group.species == "mouse":
- if len(sample.extra_attributes['rrid'].split(":")) > 1:
- the_rrid = sample.extra_attributes['rrid'].split(":")[
+ if len(sample.extra_attributes['36'].split(":")) > 1:
+ the_rrid = sample.extra_attributes['36'].split(":")[
1]
- sample.extra_attributes['rrid'] = [
- sample.extra_attributes['rrid']]
- sample.extra_attributes['rrid'].append(
+ sample.extra_attributes['36'] = [
+ sample.extra_attributes['36']]
+ sample.extra_attributes['36'].append(
webqtlConfig.RRID_MOUSE_URL % the_rrid)
elif self.dataset.group.species == "rat":
- if len(str(sample.extra_attributes['rrid'])):
- the_rrid = sample.extra_attributes['rrid'].split("_")[
+ if len(str(sample.extra_attributes['36'])):
+ the_rrid = sample.extra_attributes['36'].split("_")[
1]
- sample.extra_attributes['rrid'] = [
- sample.extra_attributes['rrid']]
- sample.extra_attributes['rrid'].append(
+ sample.extra_attributes['36'] = [
+ sample.extra_attributes['36']]
+ sample.extra_attributes['36'].append(
webqtlConfig.RRID_RAT_URL % the_rrid)
self.sample_list.append(sample)
@@ -124,17 +124,19 @@ class SampleList:
# Get attribute names and distinct values for each attribute
results = g.db.execute('''
- SELECT DISTINCT CaseAttribute.Id, CaseAttribute.Name, CaseAttributeXRefNew.Value
+ SELECT DISTINCT CaseAttribute.Id, CaseAttribute.Name, CaseAttribute.Description, CaseAttributeXRefNew.Value
FROM CaseAttribute, CaseAttributeXRefNew
WHERE CaseAttributeXRefNew.CaseAttributeId = CaseAttribute.Id
AND CaseAttributeXRefNew.InbredSetId = %s
- ORDER BY lower(CaseAttribute.Name)''', (str(self.dataset.group.id),))
+ ORDER BY CaseAttribute.Id''', (str(self.dataset.group.id),))
self.attributes = {}
- for attr, values in itertools.groupby(results.fetchall(), lambda row: (row.Id, row.Name)):
- key, name = attr
+ for attr, values in itertools.groupby(results.fetchall(), lambda row: (row.Id, row.Name, row.Description)):
+ key, name, description = attr
self.attributes[key] = Bunch()
+ self.attributes[key].id = key
self.attributes[key].name = name
+ self.attributes[key].description = description
self.attributes[key].distinct_values = [
item.Value for item in values]
self.attributes[key].distinct_values = natural_sort(
@@ -168,10 +170,13 @@ class SampleList:
for sample_name, items in itertools.groupby(results.fetchall(), lambda row: row.SampleName):
attribute_values = {}
+ # Make a list of attr IDs without values (that have values for other samples)
+ valueless_attr_ids = [self.attributes[key].id for key in self.attributes.keys()]
for item in items:
+ valueless_attr_ids.remove(item.Id)
attribute_value = item.Value
- # ZS: If it's an int, turn it into one for sorting
+ # If it's an int, turn it into one for sorting
# (for example, 101 would be lower than 80 if
# they're strings instead of ints)
try:
@@ -179,8 +184,10 @@ class SampleList:
except ValueError:
pass
- attribute_values[self.attributes[item.Id].name.lower(
- )] = attribute_value
+ attribute_values[str(item.Id)] = attribute_value
+ for attr_id in valueless_attr_ids:
+ attribute_values[str(attr_id)] = ""
+
self.sample_attribute_values[sample_name] = attribute_values
def get_first_attr_col(self):
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index c07430dd..c4d1ae1c 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -1,3 +1,5 @@
+from typing import Dict
+
import string
import datetime
import uuid
@@ -176,11 +178,11 @@ class ShowTrait:
self.sample_group_types['samples_primary'] = self.dataset.group.name
sample_lists = [group.sample_list for group in self.sample_groups]
- categorical_var_list = []
+ self.categorical_var_list = []
self.numerical_var_list = []
if not self.temp_trait:
# ZS: Only using first samplelist, since I think mapping only uses those samples
- categorical_var_list = get_categorical_variables(
+ self.categorical_var_list = get_categorical_variables(
self.this_trait, self.sample_groups[0])
self.numerical_var_list = get_numerical_variables(
self.this_trait, self.sample_groups[0])
@@ -192,6 +194,8 @@ class ShowTrait:
[self.dataset.species.chromosomes.chromosomes[this_chr].name, i])
self.genofiles = self.dataset.group.get_genofiles()
+ study_samplelist_json = self.dataset.group.get_study_samplelists()
+ self.study_samplelists = [study["title"] for study in study_samplelist_json]
# ZS: No need to grab scales from .geno file unless it's using
# a mapping method that reads .geno files
@@ -280,10 +284,11 @@ class ShowTrait:
hddn['selected_chr'] = -1
hddn['mapping_display_all'] = True
hddn['suggestive'] = 0
+ hddn['study_samplelists'] = json.dumps(study_samplelist_json)
hddn['num_perm'] = 0
hddn['categorical_vars'] = ""
- if categorical_var_list:
- hddn['categorical_vars'] = ",".join(categorical_var_list)
+ if self.categorical_var_list:
+ hddn['categorical_vars'] = ",".join(self.categorical_var_list)
hddn['manhattan_plot'] = ""
hddn['control_marker'] = ""
if not self.temp_trait:
@@ -295,7 +300,7 @@ class ShowTrait:
hddn['compare_traits'] = []
hddn['export_data'] = ""
hddn['export_format'] = "excel"
- if len(self.scales_in_geno) < 2:
+ if len(self.scales_in_geno) < 2 and bool(self.scales_in_geno):
hddn['mapping_scale'] = self.scales_in_geno[list(
self.scales_in_geno.keys())[0]][0][0]
@@ -318,7 +323,7 @@ class ShowTrait:
has_num_cases=self.has_num_cases,
attributes=self.sample_groups[0].attributes,
categorical_attr_exists=self.categorical_attr_exists,
- categorical_vars=",".join(categorical_var_list),
+ categorical_vars=",".join(self.categorical_var_list),
num_values=self.num_values,
qnorm_values=self.qnorm_vals,
zscore_values=self.z_scores,
@@ -520,6 +525,9 @@ class ShowTrait:
sample_group_type='primary',
header="%s Only" % (self.dataset.group.name))
self.sample_groups = (primary_samples,)
+ print("\nttttttttttttttttttttttttttttttttttttttttttttt\n")
+ print(self.sample_groups)
+ print("\nttttttttttttttttttttttttttttttttttttttttttttt\n")
self.primary_sample_names = primary_sample_names
self.dataset.group.allsamples = all_samples_ordered
@@ -693,7 +701,7 @@ def get_categorical_variables(this_trait, sample_list) -> list:
if len(sample_list.attributes) > 0:
for attribute in sample_list.attributes:
if len(sample_list.attributes[attribute].distinct_values) < 10:
- categorical_var_list.append(sample_list.attributes[attribute].name)
+ categorical_var_list.append(str(sample_list.attributes[attribute].id))
return categorical_var_list
@@ -799,3 +807,41 @@ def get_scales_from_genofile(file_location):
return [["physic", "Mb"], ["morgan", "cM"]]
else:
return [["physic", "Mb"]]
+
+
+
+def get_diff_of_vals(new_vals: Dict, trait_id: str) -> Dict:
+ """ Get the diff between current sample values and the values in the DB
+
+ Given a dict of the changed values and the trait/dataset ID, return a Dict
+ with keys corresponding to each sample with a changed value and a value
+ that is a dict with keys for the old_value and new_value
+
+ """
+
+ trait_name = trait_id.split(":")[0]
+ dataset_name = trait_id.split(":")[1]
+ trait_ob = create_trait(name=trait_name, dataset_name=dataset_name)
+
+ old_vals = {sample : trait_ob.data[sample].value for sample in trait_ob.data}
+
+ shared_samples = set.union(set(new_vals.keys()), set(old_vals.keys()))
+
+ diff_dict = {}
+ for sample in shared_samples:
+ try:
+ new_val = round(float(new_vals[sample]), 3)
+ except:
+ new_val = "x"
+ try:
+ old_val = round(float(old_vals[sample]), 3)
+ except:
+ old_val = "x"
+
+ if new_val != old_val:
+ diff_dict[sample] = {
+ "new_val": new_val,
+ "old_val": old_val
+ }
+
+ return diff_dict
diff --git a/wqflask/wqflask/static/new/css/bootstrap-custom.css b/wqflask/wqflask/static/new/css/bootstrap-custom.css
index 7c8549e1..a0d3ff6a 100644
--- a/wqflask/wqflask/static/new/css/bootstrap-custom.css
+++ b/wqflask/wqflask/static/new/css/bootstrap-custom.css
@@ -327,7 +327,7 @@ th {
font-family: 'Glyphicons Halflings';
src: url('../fonts/glyphicons-halflings-regular.eot');
- src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
@@ -7554,5 +7554,3 @@ button.close {
display: none !important;
}
}
-
-/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file
diff --git a/wqflask/wqflask/static/new/css/show_trait.css b/wqflask/wqflask/static/new/css/show_trait.css
index 0486da4d..f5e8c22a 100644
--- a/wqflask/wqflask/static/new/css/show_trait.css
+++ b/wqflask/wqflask/static/new/css/show_trait.css
@@ -159,10 +159,10 @@ div.normalize-div {
}
div.mapping-main {
- min-width: 1200px;
+ min-width: 1400px;
}
div.mapping-options {
- min-width: 500px;
+ min-width: 700px;
}
div.covar-options {
@@ -194,7 +194,7 @@ div.select-covar-div {
.selected-covariates {
overflow-y: scroll;
resize: none;
- width: 200px;
+ width: 400px;
}
.cofactor-input {
@@ -259,3 +259,33 @@ input.trait-value-input {
div.inline-div {
display: inline;
}
+
+/* div.colorbox_border {
+ border: 1px solid grey;
+} */
+div#cboxContent {
+ /* box-shadow:
+ 0 2.8px 2.2px rgba(0, 0, 0, 0.034),
+ 0 6.7px 5.3px rgba(0, 0, 0, 0.048),
+ 0 12.5px 10px rgba(0, 0, 0, 0.06),
+ 0 22.3px 17.9px rgba(0, 0, 0, 0.072),
+ 0 41.8px 33.4px rgba(0, 0, 0, 0.086),
+ 0 100px 80px rgba(0, 0, 0, 0.12) */
+
+ padding: 10px 10px 5px 10px;
+
+ -moz-box-shadow: 3px 3px 5px #535353;
+ -webkit-box-shadow: 3px 3px 5px #535353;
+ box-shadow: 3px 3px 5px #535353;
+
+ -moz-border-radius: 6px 6px 6px 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px 6px 6px 6px;
+
+ /* border: 2px solid grey; */
+}
+
+#cboxClose {
+ margin-right: 5px;
+ margin-bottom: 2px;
+}
diff --git a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
index 3e414034..00025a32 100644
--- a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
+++ b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js
@@ -65,10 +65,8 @@ if ( ! $.fn.DataTable.isDataTable( '#collection_table' ) ) {
collection_click = function() {
var this_collection_url;
- console.log("Clicking on:", $(this));
this_collection_url = $(this).find('.collection_name').prop("href");
this_collection_url += "&json";
- console.log("this_collection_url", this_collection_url);
collection_list = $("#collections_holder").html();
return $.ajax({
dataType: "json",
@@ -79,32 +77,57 @@ collection_click = function() {
submit_click = function() {
var covariates_string = "";
- var covariates_display_string = "";
+ var covariates_as_set = new Set();
+ $(".selected-covariates:first option").each(function() {
+ if ($(this).val() != ""){
+ covariates_as_set.add($(this).val() + "," + $(this).text());
+ }
+ });
$('#collections_holder').find('input[type=checkbox]:checked').each(function() {
var this_dataset, this_trait;
this_trait = $(this).parents('tr').find('.trait').text();
this_trait_display = $(this).parents('tr').find('.trait').data("display_name");
this_description = $(this).parents('tr').find('.description').text();
- console.log("this_trait is:", this_trait_display);
this_dataset = $(this).parents('tr').find('.dataset').data("dataset");
- console.log("this_dataset is:", this_dataset);
- covariates_string += this_trait + ":" + this_dataset + ","
- //this_covariate_display_string = this_trait + ": " + this_description
this_covariate_display_string = this_trait_display
if (this_covariate_display_string.length > 50) {
this_covariate_display_string = this_covariate_display_string.substring(0, 45) + "..."
}
- covariates_display_string += this_covariate_display_string + "\n"
+ covariates_as_set.add(this_trait + ":" + this_dataset + "," + this_covariate_display_string)
+ });
+
+ covariates_as_list = Array.from(covariates_as_set)
+
+ // Removed the starting "No covariates selected" option before adding options for each covariate
+ if (covariates_as_list.length > 0){
+ $(".selected-covariates option[value='']").each(function() {
+ $(this).remove();
+ });
+ }
+
+ $(".selected-covariates option").each(function() {
+ $(this).remove();
});
- // Trim the last newline from display_string
- covariates_display_string = covariates_display_string.replace(/\n$/, "")
- // Trim the last comma
- covariates_string = covariates_string.substring(0, covariates_string.length - 1)
- //covariates_display_string = covariates_display_string.substring(0, covariates_display_string.length - 2)
+ covariate_list_for_form = []
+ $.each(covariates_as_list, function (index, value) {
+ option_value = value.split(",")[0]
+ option_text = value.split(",")[1]
+ $(".selected-covariates").append($("<option/>", {
+ value: option_value,
+ text: option_text
+ }))
+ covariate_list_for_form.push(option_value)
+ });
- $("input[name=covariates]").val(covariates_string)
- $(".selected-covariates").val(covariates_display_string)
+ $("input[name=covariates]").val(covariate_list_for_form.join(","));
+
+ cofactor_count = $(".selected-covariates:first option").length;
+ if (cofactor_count > 10){
+ $(".selected-covariates").attr("size", 10);
+ } else {
+ $(".selected-covariates").attr("size", cofactor_count);
+ }
return $.colorbox.close();
};
@@ -186,9 +209,8 @@ color_by_trait = function(trait_sample_data, textStatus, jqXHR) {
process_traits = function(trait_data, textStatus, jqXHR) {
var the_html, trait, _i, _len;
console.log('in process_traits with trait_data:', trait_data);
- the_html = "<button id='back_to_collections' class='btn btn-inverse btn-small'>";
- the_html += "<i class='icon-white icon-arrow-left'></i> Back </button>";
- the_html += " <button id='submit' class='btn btn-primary btn-small'> Submit </button>";
+ the_html = "<button class='btn btn-success btn-small submit'> Submit </button>";
+ the_html += "<button id='back_to_collections' class='btn btn-inverse btn-small' style='float: right;'>Back</button>";
the_html += "<table id='collection_table' style='padding-top: 10px;' class='table table-hover'>";
the_html += "<thead><tr><th></th><th>Record</th><th>Data Set</th><th>Description</th></tr></thead>";
the_html += "<tbody>";
@@ -221,6 +243,6 @@ back_to_collections = function() {
};
$(".collection_line").on("click", collection_click);
-$("#submit").on("click", submit_click);
+$(".submit").on("click", submit_click);
$(".trait").on("click", trait_click);
-$("#back_to_collections").on("click", back_to_collections); \ No newline at end of file
+$("#back_to_collections").on("click", back_to_collections);
diff --git a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js
index 9fe61abe..897f79ff 100644
--- a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js
+++ b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js
@@ -132,16 +132,16 @@ build_columns = function() {
}
}
- attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].name.toLowerCase() > js_data.attributes[b].name.toLowerCase()) ? 1 : -1)
+ attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].id > js_data.attributes[b].id) ? 1 : -1)
for (i = 0; i < attr_keys.length; i++){
column_list.push(
{
- 'title': "<div style='text-align: " + js_data.attributes[attr_keys[i]].alignment + "'>" + js_data.attributes[attr_keys[i]].name + "</div>",
+ 'title': "<div title='" + js_data.attributes[attr_keys[i]].description + "' style='text-align: " + js_data.attributes[attr_keys[i]].alignment + "'>" + js_data.attributes[attr_keys[i]].name + "</div>",
'type': "natural",
'data': null,
'targets': attr_start + i,
'render': function(data, type, row, meta) {
- attr_name = Object.keys(data.extra_attributes).sort()[meta.col - data.first_attr_col]
+ attr_name = Object.keys(data.extra_attributes).sort((a, b) => (parseInt(a) > parseInt(b)) ? 1 : -1)[meta.col - data.first_attr_col]
if (attr_name != null && attr_name != undefined){
if (Array.isArray(data.extra_attributes[attr_name])){
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js
index 77ef1720..f050d4ae 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait.js
@@ -98,11 +98,54 @@ sample_group_types = js_data.sample_group_types;
$(".select_covariates").click(function () {
open_covariate_selection();
});
+
$(".remove_covariates").click(function () {
- $("input[name=covariates]").val("")
- $(".selected-covariates").val("")
+ $(".selected-covariates option:selected").each(function() {
+ this_val = $(this).val();
+ $(".selected-covariates option").each(function(){
+ if ($(this).val() == this_val){
+ $(this).remove();
+ }
+ })
+ cofactor_count = $(".selected-covariates:first option").length
+ if (cofactor_count > 2 && cofactor_count < 11){
+ $(".selected-covariates").each(function() {
+ $(this).attr("size", $(".selected-covariates:first option").length)
+ });
+ } else if (cofactor_count > 10) {
+ $(".selected-covariates").each(function() {
+ $(this).attr("size", 10)
+ });
+ } else {
+ $(".selected-covariates").each(function() {
+ $(this).attr("size", 2)
+ });
+ }
+ if (cofactor_count == 0){
+ $(".selected-covariates").each(function() {
+ $(this).append($("<option/>", {
+ value: "",
+ text: "No covariates selected"
+ }))
+ })
+ }
+ });
+
+ covariates_list = [];
+ $(".selected-covariates:first option").each(function() {
+ covariates_list.push($(this).val());
+ })
+ $("input[name=covariates]").val(covariates_list.join(","))
});
+$(".remove_all_covariates").click(function() {
+ $(".selected-covariates option").each(function() {
+ $(this).remove();
+ });
+ $(".selected-covariates").attr("size", 2)
+ $("input[name=covariates]").val("");
+})
+
open_trait_selection = function() {
return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) {
return function() {
@@ -608,13 +651,14 @@ $(".corr_compute").on("click", (function(_this) {
create_value_dropdown = function(value) {
return "<option val=" + value + ">" + value + "</option>";
};
+
populate_sample_attributes_values_dropdown = function() {
var attribute_info, key, sample_attributes, selected_attribute, value, _i, _len, _ref, _ref1, _results;
$('#attribute_values').empty();
sample_attributes = [];
var attributes_as_list = Object.keys(js_data.attributes).map(function(key) {
- return [key, js_data.attributes[key].name.toLowerCase()];
+ return [key, js_data.attributes[key].id];
});
attributes_as_list.sort(function(first, second) {
@@ -628,7 +672,7 @@ populate_sample_attributes_values_dropdown = function() {
});
for (i=0; i < attributes_as_list.length; i++) {
- attribute_info = js_data.attributes[attributes_as_list[i][0]]
+ attribute_info = js_data.attributes[attributes_as_list[i][1]]
sample_attributes.push(attribute_info.distinct_values);
}
@@ -667,11 +711,13 @@ block_by_attribute_value = function() {
let exclude_val_nodes = table_api.column(attribute_start_pos + parseInt(exclude_column)).nodes().to$();
for (i = 0; i < exclude_val_nodes.length; i++) {
- let this_col_value = exclude_val_nodes[i].childNodes[0].data;
- let this_val_node = val_nodes[i].childNodes[0];
+ if (exclude_val_nodes[i].hasChildNodes()) {
+ let this_col_value = exclude_val_nodes[i].childNodes[0].data;
+ let this_val_node = val_nodes[i].childNodes[0];
- if (this_col_value == exclude_by_value){
- this_val_node.value = "x";
+ if (this_col_value == exclude_by_value){
+ this_val_node.value = "x";
+ }
}
}
@@ -713,10 +759,34 @@ block_by_index = function() {
for (_k = 0, _len1 = index_list.length; _k < _len1; _k++) {
index = index_list[_k];
val_nodes[index - 1].childNodes[0].value = "x";
-
}
};
+filter_by_study = function() {
+ let this_study = $('#filter_study').val();
+
+ let study_sample_data = JSON.parse($('input[name=study_samplelists]').val())
+ let filter_samples = study_sample_data[parseInt(this_study)]['samples']
+
+ if ($('#filter_study_group').length){
+ let block_group = $('#filter_study_group').val();
+ if (block_group === "other") {
+ table_api = $('#samples_other').DataTable();
+ } else {
+ table_api = $('#samples_primary').DataTable();
+ }
+ }
+
+ let sample_nodes = table_api.column(2).nodes().to$();
+ let val_nodes = table_api.column(3).nodes().to$();
+ for (i = 0; i < sample_nodes.length; i++) {
+ this_sample = sample_nodes[i].childNodes[0].innerText;
+ if (!filter_samples.includes(this_sample)){
+ val_nodes[i].childNodes[0].value = "x";
+ }
+ }
+}
+
filter_by_value = function() {
let filter_logic = $('#filter_logic').val();
let filter_column = $('#filter_column').val();
@@ -748,7 +818,7 @@ filter_by_value = function() {
var this_col_value = filter_val_nodes[i].childNodes[0].value;
} else {
if (filter_val_nodes[i].childNodes[0] !== undefined){
- var this_col_value = filter_val_nodes[i].childNodes[0].data;
+ var this_col_value = filter_val_nodes[i].innerText;
} else {
continue
}
@@ -1690,6 +1760,11 @@ $('#block_by_index').click(function(){
edit_data_change();
});
+$('#filter_by_study').click(function(){
+ filter_by_study();
+ edit_data_change();
+})
+
$('#filter_by_value').click(function(){
filter_by_value();
edit_data_change();
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 09e9d024..e42fe8c4 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
@@ -141,11 +141,11 @@ $('input[name=display_all]').change((function(_this) {
})(this));
//ZS: This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping
-var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', 'sample_vals',
- 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results',
- 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker', 'do_control', 'genofile',
- 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck',
- 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'reaper_version', 'primary_samples']
+var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale',
+ 'sample_vals', 'vals_hash', 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars',
+ 'num_bootstrap', 'bootCheck', 'bootstrap_results', 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker',
+ 'do_control', 'genofile', 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend',
+ 'haplotypeAnalystCheck', 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'primary_samples']
$(".rqtl-geno-tab, #rqtl_geno_compute").on("click", (function(_this) {
return function() {
diff --git a/wqflask/wqflask/templates/admin/group_manager.html b/wqflask/wqflask/templates/admin/group_manager.html
index c0b99e75..692a7abc 100644
--- a/wqflask/wqflask/templates/admin/group_manager.html
+++ b/wqflask/wqflask/templates/admin/group_manager.html
@@ -81,7 +81,7 @@
<tr>
<td><input type="checkbox" name="read" value="{{ group.id }}"></td>
<td>{{ loop.index }}</td>
- <td>{{ group.name }}</td>
+ <td><a href="/groups/view?id={{ group.id }}">{{ group.name }}</a></td>
<td>{{ group.admins|length + group.members|length }}</td>
<td>{{ group.created_timestamp }}</td>
<td>{{ group.changed_timestamp }}</td>
diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html
index 1a0335b6..d30c575a 100644
--- a/wqflask/wqflask/templates/base.html
+++ b/wqflask/wqflask/templates/base.html
@@ -87,6 +87,7 @@
<li><a href="https://systems-genetics.org/">Systems Genetics PheWAS</a></li>
<li><a href="http://ucscbrowser.genenetwork.org/">Genome Browser</a></li>
<li><a href="http://power.genenetwork.org">BXD Power Calculator</a></li>
+ <li><a href="http://notebook.genenetwork.org/">Jupyter Notebook Launcher</a></li>
<li><a href="http://datafiles.genenetwork.org">Interplanetary File System</a></li>
</ul>
</li>
@@ -208,7 +209,7 @@
<a href="http://joss.theoj.org/papers/10.21105/joss.00025"><img src="https://camo.githubusercontent.com/846b750f582ae8f1d0b4f7e8fee78bed705c88ba/687474703a2f2f6a6f73732e7468656f6a2e6f72672f7061706572732f31302e32313130352f6a6f73732e30303032352f7374617475732e737667" alt="JOSS" data-canonical-src="http://joss.theoj.org/papers/10.21105/joss.00025/status.svg" style="max-width:100%;"></a>
</p>
<p>
- Development and source code on <a href="https://github.com/genenetwork/">github</a> with <a href="https://github.com/genenetwork/genenetwork2/issues">issue tracker</a> and <a href="https://github.com/genenetwork/genenetwork2/blob/master/README.md">documentation</a>. Join the <a href="http://listserv.uthsc.edu/mailman/listinfo/genenetwork-dev">mailing list</a> and find us on <span class="broken_link" href="https://webchat.freenode.net/">IRC</span> (#genenetwork channel).
+ Development and source code on <a href="https://github.com/genenetwork/">github</a> with <a href="https://github.com/genenetwork/genenetwork2/issues">issue tracker</a> and <a href="https://github.com/genenetwork/genenetwork2/blob/master/README.md">documentation</a>. Join the <span class="broken_link" href="http://listserv.uthsc.edu/mailman/listinfo/genenetwork-dev">mailing list</span> and find us on <a href="https://webchat.freenode.net#genenetwork">IRC</a> (#genenetwork channel).
{% if version: %}
<p><small>GeneNetwork {{ version }}</small></p>
{% endif %}
diff --git a/wqflask/wqflask/templates/collections/add.html b/wqflask/wqflask/templates/collections/add.html
index 0398c6e4..8640fdb8 100644
--- a/wqflask/wqflask/templates/collections/add.html
+++ b/wqflask/wqflask/templates/collections/add.html
@@ -5,7 +5,7 @@
or add to an existing collection.</p>
</div>
<div class="modal-body" style="margin-left: 20px;">
- <form action="/collections/new" target="_blank" data-validate="parsley" id="add_form">
+ <form action="/collections/new" target="_blank" data-validate="parsley" id="add_form" class="form-inline">
{% if traits is defined %}
<input type="hidden" name="traits" value="{{ traits }}" />
{% else %}
@@ -14,10 +14,8 @@
{% if collections|length > 0 %}
<fieldset>
<legend>1. Add to an existing collection</legend>
- <div style="margin-left: 20px;">
- <!--<label>Existing collection name:</label>-->
- <select name="existing_collection" class="form-control">
- <!--<option selected disabled>Select Collection</option>-->
+ <div style="margin-left: 20px;">
+ <select name="existing_collection" class="form-control" style="width: 80%;">
{% for col in collections %}
{% if loop.index == 1 %}
<option value="{{ col.id }}:{{ col.name }}" selected>{{ col.name }}</option>
@@ -26,8 +24,9 @@
{% endif %}
{% endfor %}
</select>
- <br />
- <button type="submit" name="add_to_existing" class="btn btn-primary">Add to existing collection</button>
+ <input type="button" style="display: inline;" id="make_default" value="Make Default">
+ <br><br>
+ <button type="submit" name="add_to_existing" class="btn btn-primary">Add</button>
</div>
</fieldset>
{% endif %}
@@ -35,7 +34,6 @@
<fieldset>
<legend>{% if collections|length > 0 %}2. {% else %}{% endif %}Create a new collection</legend>
<div style="margin-left: 20px;">
- <!--<label>Collection name:</label>-->
<input type="text" name="new_collection" placeholder=" Name of new collection..."
data-trigger="change" data-minlength="5" data-maxlength="50" style="width: 100%">
<button type="submit" name="create_new" class="btn btn-primary" style="margin-top: 20px;">Create collection</button>
@@ -54,6 +52,21 @@
parent.jQuery.colorbox.close();
});
+ make_default = function() {
+ alert("The current collection is now your default collection.")
+ let uc_id = $('[name=existing_collection] option:selected').val().split(":")[0]
+ $.cookie('default_collection', uc_id, {
+ expires: 365,
+ path: '/'
+ });
+
+ let default_collection_id = $.cookie('default_collection');
+ };
+
+ $("#make_default").on("click", function(){
+ make_default();
+ });
+
apply_default = function() {
let default_collection_id = $.cookie('default_collection');
if (default_collection_id) {
diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html
index 9ec98ab1..a3090bcf 100644
--- a/wqflask/wqflask/templates/collections/view.html
+++ b/wqflask/wqflask/templates/collections/view.html
@@ -49,7 +49,7 @@
<input type="text" id="select_top" class="form-control" style="width: 200px; display: inline; padding-bottom: 9px;" placeholder="Select Top ...">
<button class="btn btn-default" id="deselect_all" type="button"><span class="glyphicon glyphicon-remove"></span> Deselect</button>
<button id="remove" class="btn btn-danger" data-url="/collections/remove" type="button" disabled><i class="icon-minus-sign"></i> Delete Rows</button>
- <button id="delete" class="btn btn-danger submit_special" data-url="/collections/delete" title="Delete this collection" > Delete Collection</button>
+ <button id="delete" class="btn btn-danger submit_special" data-url="/collections/delete" type="button" title="Delete this collection" > Delete Collection</button>
</form>
</div>
<div style="margin-top: 10px; margin-bottom: 5px;">
diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html
index 4cad2749..f66eb4bd 100644
--- a/wqflask/wqflask/templates/correlation_page.html
+++ b/wqflask/wqflask/templates/correlation_page.html
@@ -17,9 +17,9 @@
<hr style="height: 1px; background-color: #A9A9A9;">
</div>
<div style="max-width: 100%;">
- <p>Values of record {{ this_trait.name }} in the <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if dataset.accession_id != 'None' %}GN_AccessionId={{ dataset.accession_id }}{% else %}InfoPageName={{ dataset.name }}{% endif %}">{{ dataset.fullname }}</a>
+ <p>Values of record {{ this_trait.name }} in the <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if this_dataset.accession_id != 'None' %}GN_AccessionId={{ this_dataset.accession_id }}{% else %}InfoPageName={{ this_dataset.name }}{% endif %}">{{ this_dataset.fullname }}</a>
dataset were compared to all records in the <a href="http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&{% if target_dataset.accession_id != 'None' %}GN_AccessionId={{ target_dataset.accession_id }}{% else %}InfoPageName={{ target_dataset.name }}{% endif %}">{{ target_dataset.fullname }}</a>
- dataset. The top {{ return_number }} correlations ranked by the {{ formatted_corr_type }} are displayed.
+ dataset. The top {{ return_results }} correlations ranked by the {{ formatted_corr_type }} are displayed.
You can resort this list by clicking the headers. Select the Record ID to open the trait data
and analysis page.
</p>
@@ -30,7 +30,7 @@
<input type="hidden" name="form_url" value="" />
<input type="hidden" name="trait_list" id="trait_list" value= "
{% for this_trait in trait_list %}
- {{ this_trait.name }}:{{ this_trait.dataset }},
+ {{ this_trait }}:{{ this_dataset.name }},
{% endfor %}" >
{% include 'tool_buttons.html' %}
</form>
@@ -43,7 +43,7 @@
<button class="btn btn-success" id="add" type="button" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
<input type="hidden" name="database_name" id="database_name" value="None">
<input type="hidden" name="export_data" id="export_data" value="">
- <input type="hidden" name="file_name" id="file_name" value="{{ this_trait.name }}_{{ dataset.name }}_correlation">
+ <input type="hidden" name="file_name" id="file_name" value="{{ this_trait.name }}_{{ this_dataset.name }}_correlation">
<input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline;" placeholder="Search Table For ...">
<input type="text" id="select_top" class="form-control" style="width: 200px; display: inline;" placeholder="Select Top ...">
<button class="btn btn-default" id="deselect_all" type="button"><span class="glyphicon glyphicon-remove"></span> Deselect</button>
@@ -146,7 +146,7 @@
<script type="text/javascript" charset="utf-8">
- var table_json = {{ json_results | safe }}
+ var table_json = {{ table_json | safe }}
</script>
<script type="text/javascript" charset="utf-8">
@@ -313,7 +313,7 @@
'orderSequence': [ "desc", "asc"],
'render': function(data, type, row, meta) {
if (data.sample_r != "N/A") {
- return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if dataset.name == 'Temp' %}Temp_{{ dataset.group.name }}{% else %}{{ dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if this_dataset.name == 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
} else {
return data.sample_r
}
@@ -441,7 +441,7 @@
'orderSequence': [ "desc", "asc"],
'render': function(data, type, row, meta) {
if (data.sample_r != "N/A") {
- return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if dataset.name == 'Temp' %}Temp_{{ dataset.group.name }}{% else %}{{ dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if this_dataset.name== 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
} else {
return data.sample_r
}
@@ -495,7 +495,7 @@
'orderSequence': [ "desc", "asc"],
'render': function(data, type, row, meta) {
if (data.sample_r != "N/A") {
- return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if dataset.name == 'Temp' %}Temp_{{ dataset.group.name }}{% else %}{{ dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
+ return "<a target\"_blank\" href=\"corr_scatter_plot?method={% if corr_method == 'spearman' %}spearman{% else %}pearson{% endif %}&dataset_1={% if this_dataset.name == 'Temp' %}Temp_{{ this_dataset.group }}{% else %}{{ this_dataset.name }}{% endif %}&dataset_2=" + data.dataset + "&trait_1={{ this_trait.name }}&trait_2=" + data.trait_id + "\">" + data.sample_r + "</a>"
} else {
return data.sample_r
}
diff --git a/wqflask/wqflask/templates/display_files_admin.html b/wqflask/wqflask/templates/display_files_admin.html
new file mode 100644
index 00000000..4b4babc4
--- /dev/null
+++ b/wqflask/wqflask/templates/display_files_admin.html
@@ -0,0 +1,32 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+{% with messages = get_flashed_messages(with_categories=true) %}
+{% if messages %}
+{% for category, message in messages %}
+<div class="container-fluid bg-{{ category }}">
+ <p>{{ message }}</p>
+</div>
+{% endfor %}
+{% endif %}
+{% endwith %}
+Show files for approval
+
+<div>
+ <ul>
+ {% for file in files %}
+ <li><a href="/display-file/{{ file }}" target="_blank">{{ file }}</a><br/>
+ <button><a href="/data-samples/approve/{{ file }}">Approve</a></button>
+ <button><a href="/data-samples/reject/{{ file }}">Reject</a></button></li>
+ {% endfor %}
+ </ul>
+</div>
+{%endblock%}
+
+{% block js %}
+<script>
+ gn_server_url = "{{ gn_server_url }}";
+
+</script>
+{% endblock %}
diff --git a/wqflask/wqflask/templates/display_files_user.html b/wqflask/wqflask/templates/display_files_user.html
new file mode 100644
index 00000000..b6bab709
--- /dev/null
+++ b/wqflask/wqflask/templates/display_files_user.html
@@ -0,0 +1,31 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+{% with messages = get_flashed_messages(with_categories=true) %}
+{% if messages %}
+{% for category, message in messages %}
+<div class="container-fluid bg-{{ category }}">
+ <p>{{ message }}</p>
+</div>
+{% endfor %}
+{% endif %}
+{% endwith %}
+Show files for approval
+
+<div>
+ <ul>
+ {% for file in files %}
+ <li><a href="/display-file/{{ file }}" target="_blank">{{ file }}</a><br/>
+ <button><a href="/data-samples/reject/{{ file }}">Reject</a></button></li>
+ {% endfor %}
+ </ul>
+</div>
+{%endblock%}
+
+{% block js %}
+<script>
+ gn_server_url = "{{ gn_server_url }}";
+
+</script>
+{% endblock %}
diff --git a/wqflask/wqflask/templates/edit_trait.html b/wqflask/wqflask/templates/edit_phenotype.html
index 7d4c65f8..7a841793 100644
--- a/wqflask/wqflask/templates/edit_trait.html
+++ b/wqflask/wqflask/templates/edit_phenotype.html
@@ -2,8 +2,18 @@
{% block title %}Trait Submission{% endblock %}
{% block content %}
<!-- Start of body -->
-Edit Trait for Published Database
-Submit Trait | Reset
+{% with messages = get_flashed_messages(with_categories=true) %}
+{% if messages %}
+{% for category, message in messages %}
+<div class="container-fluid bg-{{ category }}">
+ <p>{{ message }}</p>
+</div>
+{% endfor %}
+{% endif %}
+{% endwith %}
+<div class="page-header text-center">
+ <h1>Edit Trait for Published Database</h1>
+</div>
{% if diff %}
@@ -53,7 +63,7 @@ Submit Trait | Reset
{% endif %}
-<form id="edit-form" class="form-horizontal" method="post" action="/trait/update">
+<form id="edit-form" class="form-horizontal" method="post" action="/trait/update" enctype=multipart/form-data>
<h2 class="text-center">Trait Information:</h2>
<div class="form-group">
<label for="pubmed-id" class="col-sm-2 control-label">Pubmed ID:</label>
@@ -207,10 +217,18 @@ Submit Trait | Reset
<input name="old_sequence" class="changed" type="hidden" value="{{ publication.sequence |default('', true) }}"/>
</div>
</div>
- <div class="controls" style="display:block; margin-left: 40%; margin-right: 20%;">
+ <div style="margin-left: 13%;">
+ <a href="/trait/{{ publish_xref.id_ }}/sampledata/{{ publish_xref.phenotype_id }}" class="btn btn-link btn-sm">
+ Sample Data(CSV Download)
+ </a>
+ </div>
+ <div class="form-group">
+ <input type = "file" class="col-sm-4 control-label" name = "file" />
+ </div>
+ <div class="controls center-block" style="width: max-content;">
<input name="dataset-name" class="changed" type="hidden" value="{{ publish_xref.id_ }}"/>
- <input name="phenotype-id" class="changed" type="hidden" value="{{ publish_xref.phenotype_id }}"/>
<input name="inbred-set-id" class="changed" type="hidden" value="{{ publish_xref.inbred_set_id }}"/>
+ <input name="phenotype-id" class="changed" type="hidden" value="{{ publish_xref.phenotype_id }}"/>
<input name="comments" class="changed" type="hidden" value="{{ publish_xref.comments }}"/>
<input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-primary form-control col-xs-2 changed" value="Submit Change">
<input type="reset" style="width: 110px;" class="btn btn-primary form-control col-xs-2 changed" onClick="window.location.reload();" value="Reset">
diff --git a/wqflask/wqflask/templates/edit_probeset.html b/wqflask/wqflask/templates/edit_probeset.html
new file mode 100644
index 00000000..85d49561
--- /dev/null
+++ b/wqflask/wqflask/templates/edit_probeset.html
@@ -0,0 +1,239 @@
+{% extends "base.html" %}
+{% block title %}Trait Submission{% endblock %}
+{% block content %}
+<!-- Start of body -->
+Edit Trait for Probeset
+Submit Trait | Reset
+
+{% if diff %}
+
+<div class="container">
+ <details class="col-sm-12 col-md-10 col-lg-12">
+ <summary>
+ <h2>Update History</h2>
+ </summary>
+ <table class="table">
+ <tbody>
+ <tr>
+ <th>Timestamp</th>
+ <th>Editor</th>
+ <th>Field</th>
+ <th>Diff</th>
+ </tr>
+ {% set ns = namespace(display_cell=True) %}
+
+ {% for timestamp, group in diff %}
+ {% set ns.display_cell = True %}
+ {% for i in group %}
+ <tr>
+ {% if ns.display_cell and i.timestamp == timestamp %}
+
+ {% set author = i.author %}
+ {% set timestamp_ = i.timestamp %}
+
+ {% else %}
+
+ {% set author = "" %}
+ {% set timestamp_ = "" %}
+
+ {% endif %}
+ <td>{{ timestamp_ }}</td>
+ <td>{{ author }}</td>
+ <td>{{ i.diff.field }}</td>
+ <td><pre>{{ i.diff.diff }}</pre></td>
+ {% set ns.display_cell = False %}
+ </tr>
+ {% endfor %}
+ {% endfor %}
+ </tbody>
+ </table>
+ </details>
+
+</div>
+
+{% endif %}
+
+<form id="edit-form" class="form-horizontal" method="post" action="/probeset/update">
+ <h2 class="text-center">Probeset Information:</h2>
+ <div class="form-group">
+ <label for="symbol" class="col-sm-2 control-label">Symbol:</label>
+ <div class="col-sm-4">
+ <textarea name="symbol" class="form-control" rows="1">{{ probeset.symbol |default('', true) }}</textarea>
+ <input name="old_symbol" class="changed" type="hidden" value="{{ probeset.symbol |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="description" class="col-sm-2 control-label">Description:</label>
+ <div class="col-sm-5">
+ <textarea name="description" class="form-control" rows="3">{{ probeset.description |default('', true) }}</textarea>
+ <input name="old_description" class="changed" type="hidden" value="{{ probeset.description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_target_description" class="col-sm-2 control-label">Probe Target Description:</label>
+ <div class="col-sm-4">
+ <textarea name="probe_target_description" class="form-control" rows="4">{{ probeset.probe_target_description |default('', true) }}</textarea>
+ <input name="old_probe_target_description" class="changed" type="hidden" value="{{ probeset.probe_target_description |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="chr" class="col-sm-2 control-label">Chr:</label>
+ <div class="col-sm-4">
+ <textarea name="chr" class="form-control" rows="1">{{ probeset.chr_ |default('', true) }}</textarea>
+ <input name="old_chr_" class="changed" type="hidden" value="{{ probeset.chr_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="mb" class="col-sm-2 control-label">Mb:</label>
+ <div class="col-sm-4">
+ <textarea name="mb" class="form-control" rows="1">{{ probeset.mb |default('', true) }}</textarea>
+ <input name="old_mb" class="changed" type="hidden" value="{{ probeset.mb |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="alias" class="col-sm-2 control-label">
+ Alias:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="alias" class="form-control" rows="1">{{ probeset.alias |default('', true) }}</textarea>
+ <input name="old_alias" class="changed" type="hidden" value="{{ probeset.alias |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="geneid" class="col-sm-2 control-label">
+ Gene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="geneid" class="form-control" rows="1">{{ probeset.geneid |default('', true) }}</textarea>
+ <input name="old_geneid" class="changed" type="hidden" value="{{ probeset.geneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="homologeneid" class="col-sm-2 control-label">
+ Homolegene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="homologeneid" class="form-control" rows="1">{{ probeset.homologeneid |default('', true) }}</textarea>
+ <input name="old_homologeneid" class="changed" type="hidden" value="{{ probeset.homologeneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="unigeneid" class="col-sm-2 control-label">
+ Unigene Id:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="unigeneid" class="form-control" rows="1">{{ probeset.unigeneid |default('', true) }}</textarea>
+ <input name="old_unigeneid" class="changed" type="hidden" value="{{ probeset.unigeneid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="omim" class="col-sm-2 control-label">OMIM:</label>
+ <div class="col-sm-4">
+ <textarea name="omim" class="form-control" rows="1">{{ probeset.omim |default('', true) }}</textarea>
+ <input name="old_omim" class="changed" type="hidden" value="{{ probeset.omim |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="refseq_transcriptid" class="col-sm-2 control-label">
+ Refseq TranscriptId:
+ </label>
+ <div class="col-sm-4">
+ <textarea name="refseq_transcriptid" class="form-control" rows="1">{{ probeset.refseq_transcriptid |default('', true) }}</textarea>
+ <input name="old_refseq_transcriptid" class="changed" type="hidden" value="{{ probeset.refseq_transcriptid |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="blatseq" class="col-sm-2 control-label">BlatSeq:</label>
+ <div class="col-sm-8">
+ <textarea name="blatseq" class="form-control" rows="6">{{ probeset.blatseq |default('', true) }}</textarea>
+ <input name="old_blatseq" class="changed" type="hidden" value="{{ probeset.blatseq |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="targetseq" class="col-sm-2 control-label">TargetSeq:</label>
+ <div class="col-sm-8">
+ <textarea name="targetseq" class="form-control" rows="6">{{ probeset.targetseq |default('', true) }}</textarea>
+ <input name="old_targetseq" class="changed" type="hidden" value="{{ probeset.targetseq |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="strand_probe" class="col-sm-2 control-label">Strand Probe:</label>
+ <div class="col-sm-2">
+ <textarea name="strand_probe" class="form-control" rows="1">{{ probeset.strand_probe |default('', true) }}</textarea>
+ <input name="old_strand_probe" class="changed" type="hidden" value="{{ probeset.strand_probe |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_target_region" class="col-sm-2 control-label">Probe Set Target Region:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_target_region" class="form-control" rows="1">{{ probeset.probe_set_target_region |default('', true) }}</textarea>
+ <input name="old_probe_set_target_region" class="changed" type="hidden" value="{{ probeset.probe_set_target_region_ |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_specificity" class="col-sm-2 control-label">Probeset Specificity:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_specificity" class="form-control" rows="1">{{ probeset.probe_set_specificity |default('', true) }}</textarea>
+ <input name="old_probe_set_specificity" class="changed" type="hidden" value="{{ probeset.probe_set_specificity |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_score" class="col-sm-2 control-label">Probeset Blat Score:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_score" class="form-control" rows="1">{{ probeset.probe_set_blat_score |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_score" class="changed" type="hidden" value="{{ probeset.probe_set_blat_score |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_mb_start" class="col-sm-2 control-label">
+ Probeset Blat Mb Start:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_mb_start" class="form-control" rows="1">{{ probeset.probe_set_blat_mb_start |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_mb_start" class="changed" type="hidden" value="{{ probeset.probe_set_blat_mb_start |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_blat_mb_end" class="col-sm-2 control-label">Probeset Blat Mb End:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_blat_mb_end" class="form-control" rows="6">{{ probeset.probe_set_blat_mb_end |default('', true) }}</textarea>
+ <input name="old_probe_set_blat_mb_end" class="changed" type="hidden" value="{{ probeset.probe_set_blat_mb_end |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_strand" class="col-sm-2 control-label">Probeset Strand:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_strand" class="form-control" rows="6">{{ probeset.probe_set_strand |default('', true) }}</textarea>
+ <input name="old_probe_set_strand" class="changed" type="hidden" value="{{ probeset.probe_set_strand |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="probe_set_note_by_rw" class="col-sm-2 control-label">Probeset Strand:</label>
+ <div class="col-sm-8">
+ <textarea name="probe_set_note_by_rw" class="form-control" rows="6">{{ probeset.probe_set_note_by_rw |default('', true) }}</textarea>
+ <input name="old_probe_set_note_by_rw" class="changed" type="hidden" value="{{ probeset.probe_set_note_by_rw |default('', true) }}"/>
+ </div>
+ </div>
+ <div class="controls" style="display:block; margin-left: 40%; margin-right: 20%;">
+ <input name="id" class="changed" type="hidden" value="{{ probeset.id_ }}"/>
+ <input name="old_id_" class="changed" type="hidden" value="{{ probeset.id_ }}"/>
+ <input name="probeset_name" class="changed" type="hidden" value="{{ probeset.name }}"/>
+ <input type="submit" style="width: 125px; margin-right: 25px;" class="btn btn-primary form-control col-xs-2 changed" value="Submit Change">
+ <input type="reset" style="width: 110px;" class="btn btn-primary form-control col-xs-2 changed" onClick="window.location.reload();" value="Reset">
+ </div>
+</form>
+
+{%endblock%}
+
+{% block js %}
+<script>
+ gn_server_url = "{{ gn_server_url }}";
+ function MarkAsChanged(){
+ $(this).addClass("changed");
+ }
+ $(":input").blur(MarkAsChanged).change(MarkAsChanged);
+
+ $("input[type=submit]").click(function(){
+ $(":input:not(.changed)").attr("disabled", "disabled");
+ });
+</script>
+{% endblock %}
diff --git a/wqflask/wqflask/templates/loading.html b/wqflask/wqflask/templates/loading.html
index 6d6136ac..ccf810b0 100644
--- a/wqflask/wqflask/templates/loading.html
+++ b/wqflask/wqflask/templates/loading.html
@@ -12,6 +12,8 @@
{% if start_vars.tool_used == "Mapping" %}
<h1>Computing the Maps</h1>
<br>
+ <b>Time Elapsed:</b> <span class="timer"></span>
+ <br>
<b>Trait Metadata</b>
<br>
species = <b><i>{{ start_vars.species[0] | upper }}{{ start_vars.species[1:] }}</i></b>
@@ -25,6 +27,8 @@
<br>
transformation = <b><i>{{ start_vars.transform }}</i></b>
{% endif %}
+ <br>
+ hash of sample values = <b><i>{{ start_vars.vals_hash }}</i></b>
<br><br>
<b>Mapping Metadata</b>
<br>
@@ -68,6 +72,29 @@
<div style="text-align: center;">
<img align="center" src="/static/gif/89.gif">
</div>
+ {% if start_vars.vals_diff|length != 0 and start_vars.transform == "" %}
+ <br><br>
+ <button id="show_full_diff">Show Full Diff</button>
+ <br>
+ <div id="diff_table_container" style="display: none; height:200px; overflow:auto;">
+ <table class="table table-hover">
+ <thead>
+ <th>Sample</th>
+ <th>New Value</th>
+ <th>Old Value</th>
+ </thead>
+ <tbody>
+ {% for sample in start_vars.vals_diff %}
+ <tr>
+ <td>{{ sample }}</td>
+ <td>{{ start_vars.vals_diff[sample].new_val }}</td>
+ <td>{{ start_vars.vals_diff[sample].old_val }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
</div>
</div>
</div>
@@ -76,6 +103,30 @@
<script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
<script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
<script type="text/javascript">
+$('#show_full_diff').click(function() {
+ if ($('#diff_table_container').is(':visible')){
+ $('#diff_table_container').hide();
+ } else {
+ $('#diff_table_container').show();
+ }
+})
+
+var start = new Date;
+
+setInterval(function() {
+ minutes = Math.floor((new Date - start) / 1000 / 60)
+ seconds = Math.round(((new Date - start) / 1000) % 60)
+ if (seconds < 10 && minutes >= 1){
+ seconds_text = "0" + seconds.toString()
+ } else {
+ seconds_text = seconds.toString()
+ }
+ if (minutes < 1) {
+ $('.timer').text(seconds_text + " seconds");
+ } else {
+ $('.timer').text(minutes.toString() + ":" + seconds_text);
+ }
+}, 100);
$("#loading_form").attr("action", "{{ start_vars.form_url }}");
setTimeout(function(){ $("#loading_form").submit()}, 350);
diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html
index d6fc6e37..f2d11e89 100644
--- a/wqflask/wqflask/templates/mapping_results.html
+++ b/wqflask/wqflask/templates/mapping_results.html
@@ -34,6 +34,7 @@
<input type="hidden" name="results_path" value="{{ mapping_results_path }}">
<input type="hidden" name="method" value="{{ mapping_method }}">
<input type="hidden" name="sample_vals" value="{{ sample_vals }}">
+ <input type="hidden" name="vals_hash" value="{{ vals_hash }}">
<input type="hidden" name="n_samples" value="{{ n_samples }}">
<input type="hidden" name="maf" value="{{ maf }}">
<input type="hidden" name="use_loco" value="{{ use_loco }}">
@@ -44,7 +45,12 @@
{% endif %}
<input type="hidden" name="num_perm" value="{{ nperm }}">
<input type="hidden" name="perm_info" value="">
- <input type="hidden" name="perm_strata" value="{{ perm_strata }}">
+ {% if categorical_vars is defined %}
+ <input type="hidden" name="categorical_vars" value="{{ categorical_vars|join(',') }}">
+ {% endif %}
+ {% if perm_strata is defined %}
+ <input type="hidden" name="perm_strata" value="True">
+ {% endif %}
<input type="hidden" name="num_bootstrap" value="{{ nboot }}">
<input type="hidden" name="do_control" value="{{ doControl }}">
<input type="hidden" name="control_marker" value="{{ controlLocus }}">
@@ -62,15 +68,16 @@
<h2>Map Viewer: Whole Genome</h2><br>
<b>Population:</b> {{ dataset.group.species|capitalize }} {{ dataset.group.name }}<br>
<b>Database:</b> {{ dataset.fullname }}<br>
- {% if dataset.type == "ProbeSet" %}<b>Trait ID:</b>{% else %}<b>Record ID:</b>{% endif %} <a href="/show_trait?trait_id={{ this_trait.name }}&dataset={{ dataset.name }}">{{ this_trait.name }}</a><br>
+ {% if dataset.type == "ProbeSet" %}<b>Trait ID:</b>{% else %}<b>Record ID:</b>{% endif %} <a href="/show_trait?trait_id={{ this_trait.name }}&dataset={{ dataset.name }}">{{ this_trait.display_name }}</a><br>
+ <b>Trait Hash: </b> {{ vals_hash }}<br>
{% if dataset.type == "ProbeSet" %}
<b>Gene Symbol:</b> <i>{{ this_trait.symbol }}</i><br>
<b>Location:</b> Chr {{ this_trait.chr }} @ {{ this_trait.mb }} Mb<br>
{% endif %}
- {% if genofile_string is defined %}
- <b>Genotypes:</b> {{ genofile_string.split(":")[1] }}
+ {% if genofile_string != "" %}
+ <b>Genotypes:</b> {{ genofile_string.split(":")[1] }}<br>
{% endif %}
- <br>
+ <b>Current Date/Time:</b> {{ current_datetime }}<br>
<br>
<a class="export_mapping_results" href="#" target="_blank" >Download Full Results</a>
</div>
@@ -357,7 +364,9 @@
{% endif %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='purescript-genome-browser/js/purescript-genetics-browser.js') }}"></script>
@@ -409,13 +418,12 @@
"info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records",
},
"order": [[1, "asc" ]],
- "sDom": "iRZtir",
- "iDisplayLength": -1,
- "autoWidth": false,
- "deferRender": true,
+ "sDom": "itir",
+ "autoWidth": true,
"bSortClasses": false,
- "scrollCollapse": false,
- "paging": false
+ "scrollY": "100vh",
+ "scroller": true,
+ "scrollCollapse": true
} );
{% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %}
$('#trait_table').dataTable( {
@@ -523,7 +531,7 @@
});
{% endif %}
- {% if mapping_method != "gemma" and mapping_method != "plink" %}
+ {% if mapping_method != "gemma" and mapping_method != "plink" and nperm > 0 and permChecked == "ON" %}
$('#download_perm').click(function(){
perm_info_dict = {
perm_data: js_data.perm_results,
diff --git a/wqflask/wqflask/templates/new_security/_scripts.html b/wqflask/wqflask/templates/new_security/_scripts.html
deleted file mode 100644
index 5fefe305..00000000
--- a/wqflask/wqflask/templates/new_security/_scripts.html
+++ /dev/null
@@ -1 +0,0 @@
-<!--<script type="text/javascript" src="/static/new/javascript/login.js"></script>-->
diff --git a/wqflask/wqflask/templates/new_security/forgot_password.html b/wqflask/wqflask/templates/new_security/forgot_password.html
index e5c42a45..60a221da 100644
--- a/wqflask/wqflask/templates/new_security/forgot_password.html
+++ b/wqflask/wqflask/templates/new_security/forgot_password.html
@@ -48,6 +48,5 @@
{% endblock %}
{% block js %}
- {% include "new_security/_scripts.html" %}
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/forgot_password_step2.html b/wqflask/wqflask/templates/new_security/forgot_password_step2.html
index b4bf41c7..1835fd4c 100644
--- a/wqflask/wqflask/templates/new_security/forgot_password_step2.html
+++ b/wqflask/wqflask/templates/new_security/forgot_password_step2.html
@@ -20,7 +20,6 @@
{% endblock %}
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html
index 095036f0..88eab6bc 100644
--- a/wqflask/wqflask/templates/new_security/login_user.html
+++ b/wqflask/wqflask/templates/new_security/login_user.html
@@ -114,31 +114,5 @@ label.error,div.error{
{% endblock %}
{% block js %}
- <!-- Disable plugin, see https://github.com/genenetwork/genenetwork2/issues/310
-
- <script type="text/javascript" src="/static/new/packages/ValidationPlugin/dist/jquery.validate.min.js"></script>
- <script>
- $(document).ready(function () {
- $("#loginUserForm").validate({
- onkeyup: false,
- onsubmit: true,
- onfocusout: function(element) { $(element).valid(); },
- rules: {
- email_address: {
- required: true,
- email: true
- },
- password: {
- required: true
- }
- }
- });
- });
-
- </script>
-
- -->
-
- {% include "new_security/_scripts.html" %}
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/password_reset.html b/wqflask/wqflask/templates/new_security/password_reset.html
index 684c12b1..e21f075c 100644
--- a/wqflask/wqflask/templates/new_security/password_reset.html
+++ b/wqflask/wqflask/templates/new_security/password_reset.html
@@ -73,7 +73,6 @@
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/register_user.html b/wqflask/wqflask/templates/new_security/register_user.html
index 3ae4488b..c2895517 100644
--- a/wqflask/wqflask/templates/new_security/register_user.html
+++ b/wqflask/wqflask/templates/new_security/register_user.html
@@ -100,7 +100,6 @@
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/registered.html b/wqflask/wqflask/templates/new_security/registered.html
index f2f58ec1..29889a97 100644
--- a/wqflask/wqflask/templates/new_security/registered.html
+++ b/wqflask/wqflask/templates/new_security/registered.html
@@ -19,7 +19,6 @@
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/thank_you.html b/wqflask/wqflask/templates/new_security/thank_you.html
index 0ff7ee8d..d4f5e574 100644
--- a/wqflask/wqflask/templates/new_security/thank_you.html
+++ b/wqflask/wqflask/templates/new_security/thank_you.html
@@ -18,7 +18,6 @@
{% endblock %}
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/new_security/verification_still_needed.html b/wqflask/wqflask/templates/new_security/verification_still_needed.html
index dc0f9e68..1f91fd8d 100644
--- a/wqflask/wqflask/templates/new_security/verification_still_needed.html
+++ b/wqflask/wqflask/templates/new_security/verification_still_needed.html
@@ -21,7 +21,6 @@
{% endblock %}
{% block js %}
- {% include "new_security/_scripts.html" %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='zxcvbn/zxcvbn.js') }}"></script>
<script type="text/javascript" src="/static/new/javascript/password_strength.js"></script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html
index e5eea4d1..72a4b560 100644
--- a/wqflask/wqflask/templates/search_result_page.html
+++ b/wqflask/wqflask/templates/search_result_page.html
@@ -54,6 +54,7 @@
A total of {{ results|count }} records were found.
</p>
+ {% if results|count > 0 %}
{% if go_term is not none %}
<p><b>The associated genes include:</b><br><br>{% for word in search_terms %}{{ word.search_term[0] }}{% endfor %}</p>
{% endif %}
@@ -134,8 +135,11 @@
</div>
</div>
{% endif %}
+ {% else %}
+ <br>
+ <button type="button" onclick="window.location.href='/'">Return To Index Page</button>
+ {% endif %}
</div>
-
<div id="myModal"></div>
<!-- End of body -->
@@ -172,6 +176,7 @@
return params;
};
+ {% if results|count > 0 %}
var tableId = "trait_table";
var width_change = 0; //ZS: For storing the change in width so overall table width can be adjusted by that amount
@@ -501,6 +506,7 @@
var table = $('#' + tableId).DataTable();
table.colReorder.reset()
});
+ {% endif %}
submit_special = function(url) {
$("#trait_submission_form").attr("action", url);
diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html
index e623a968..16a819fa 100644
--- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html
+++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html
@@ -7,8 +7,10 @@
<div class="col-xs-3 controls">
<select name="corr_type" class="form-control">
<option value="sample">Sample r</option>
+ {% if dataset.type == 'ProbeSet' %}
<option value="lit">Literature r</option>
<option value="tissue">Tissue r</option>
+ {% endif %}
</select>
</div>
</div>
@@ -70,7 +72,7 @@
<select name="corr_sample_method" class="form-control">
<option value="pearson">Pearson</option>
<option value="spearman">Spearman Rank</option>
- <!-- <option value="bicor">Biweight Midcorrelation</option> -->
+ <option value="bicor">Biweight Midcorrelation</option>
</select>
</div>
</div>
diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html
index 83f7b0ac..2a21dd24 100644
--- a/wqflask/wqflask/templates/show_trait_details.html
+++ b/wqflask/wqflask/templates/show_trait_details.html
@@ -235,7 +235,16 @@
{% endif %}
<button type="button" id="view_in_gn1" class="btn btn-primary" title="View Trait in GN1" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?cmd=show&db={{ this_trait.dataset.name }}&probeset={{ this_trait.name }}', '_blank')">Go to GN1</button>
{% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %}
- <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/trait/{{ this_trait.name }}/edit/{{ this_trait.dataset.id }}', '_blank')">Edit</button>
+ {% if this_trait.dataset.type == 'Publish' %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/trait/{{ this_trait.name }}/edit/inbredset-id/{{ this_trait.dataset.id }}', '_blank')">Edit</button>
+ {% endif %}
+
+ {% if this_trait.dataset.type == 'ProbeSet' %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/trait/edit/probeset-name/{{ this_trait.name }}', '_blank')">Edit</button>
+ {% endif %}
+ {% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('./resources/manage?resource_id={{ resource_id }}', '_blank')">Edit Privileges</button>
+ {% endif %}
{% endif %}
</div>
</div>
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index 3dd44c85..3af94ed6 100755
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -74,17 +74,20 @@
No collections available. Please add traits to a collection to use them as covariates.
{% else %}
<div class="select-covar-div">
- <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-success select-covar-button select_covariates">Select</button>
<button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ <button type="button" class="btn btn-danger select-covar-button remove_all_covariates">Clear</button>
</div>
- <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea>
+ <select size="2" name="selected_covariates_gemma" class="form-control selected-covariates" multiple>
+ <option value="">No covariates selected</option>
+ </select>
{% endif %}
</div>
</div>
<div class="mapping_method_fields form-group">
<label class="col-xs-3 control-label"></label>
<div class="col-xs-6">
- <button id="gemma_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression" value="Compute">Compute</button>
+ <button id="gemma_compute" type="button" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression" value="Compute">Compute</button>
</div>
</div>
</div>
@@ -93,15 +96,6 @@
<div class="tab-pane" id="interval_mapping">
<div class="form-horizontal section-form-div">
<div class="mapping_method_fields form-group">
- <label for="reaper_version" class="col-xs-3 control-label">Version<sup><a href="https://github.com/chfi/rust-qtlreaper" target="_blank" title="'New' is the new qtlreaper implementation written in RUST by Christian Fischer. 'Original' corresponds to the original version written in C.">?</a></sup></label>
- <div class="col-xs-3 controls">
- <select name="reaper_version" class="form-control reaper-ver-select">
- <option value="new">New</option>
- <option value="original">Original</option>
- </select>
- </div>
- </div>
- <div class="mapping_method_fields form-group">
<label for="chr_select" class="col-xs-3 control-label">Chromosome</label>
<div class="col-xs-2 controls">
<select id="chr_reaper" class="form-control chr-select">
@@ -187,7 +181,7 @@
<div class="mapping_method_fields form-group">
<label class="col-xs-3 control-label"></label>
<div class="col-xs-6">
- <button id="interval_mapping_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping" value="Compute">Compute</button>
+ <button id="interval_mapping_compute" type="button" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Interval Mapping" value="Compute">Compute</button>
</div>
</div>
</div>
@@ -226,6 +220,17 @@
</select>
</div>
</div>
+ {% else %}
+ <div class="mapping_method_fields form-group">
+ <label for="scale_select" class="col-xs-3 control-label">Map Scale</label>
+ <div class="col-xs-2 controls">
+ <select id="scale_rqtl_geno" class="form-control scale-select">
+ {% for item in scales_in_geno[dataset.group.name + ".geno"] %}
+ <option value="{{ item[0] }}">{{ item[1] }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
{% endif %}
<div class="mapping_method_fields form-group">
<label for="mapping_permutations" class="col-xs-3 control-label">Permutations</label>
@@ -249,21 +254,6 @@
</div>
{% endif %}
<div class="mapping_method_fields form-group">
- <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
- <div class="col-xs-6 controls">
- <input name="control_rqtl_geno" value="{% if dataset.type == 'ProbeSet' and this_trait.locus_chr != '' %}{{ nearest_marker }}{% endif %}" type="text" class="form-control cofactor-input" />
- <label class="radio-inline">
- <input type="radio" name="do_control_rqtl" value="true">
- Yes
- </label>
- <label class="radio-inline">
- <input type="radio" name="do_control_rqtl" value="false" checked="">
- No
- </label>
- </div>
- </div>
-
- <div class="mapping_method_fields form-group">
<label for="mapmodel_rqtl_geno" class="col-xs-3 control-label">Model</label>
<div class="col-xs-4 controls">
<select id="mapmodel_rqtl_geno" name="mapmodel_rqtl_geno" class="form-control">
@@ -317,17 +307,20 @@
No collections available. Please add traits to a collection to use them as covariates.
{% else %}
<div class="select-covar-div">
- <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-success select-covar-button select_covariates">Select</button>
<button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ <button type="button" class="btn btn-danger select-covar-button remove_all_covariates">Clear</button>
</div>
- <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea>
+ <select size="2" name="selected_covariates_rqtl" class="form-control selected-covariates" multiple>
+ <option value="">No covariates selected</option>
+ </select>
{% endif %}
</div>
</div>
<div class="mapping_method_fields form-group">
<label class="col-xs-3 control-label"></label>
<div class="col-xs-6 controls">
- <button id="rqtl_geno_compute" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression" value="Compute">Compute</button>
+ <button id="rqtl_geno_compute" type="button" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Marker Regression" value="Compute">Compute</button>
</div>
</div>
</div>
diff --git a/wqflask/wqflask/templates/show_trait_transform_and_filter.html b/wqflask/wqflask/templates/show_trait_transform_and_filter.html
index 20f78b48..5e6ed2cf 100644
--- a/wqflask/wqflask/templates/show_trait_transform_and_filter.html
+++ b/wqflask/wqflask/templates/show_trait_transform_and_filter.html
@@ -25,7 +25,7 @@
<label for="exclude_column">Block samples by group:</label>
<select id="exclude_column" size=1>
{% for attribute in sample_groups[0].attributes %}
- {% if sample_groups[0].attributes[attribute].distinct_values|length <= 10 %}
+ {% if sample_groups[0].attributes[attribute].distinct_values|length <= 10 and sample_groups[0].attributes[attribute].distinct_values|length > 1 %}
<option value="{{ loop.index }}">
{{ sample_groups[0].attributes[attribute].name }}
</option>
@@ -45,6 +45,27 @@
<input type="button" id="exclude_by_attr" class="btn btn-danger" value="Block">
</div>
{% endif %}
+ {% if study_samplelists|length > 0 %}
+ <div id="filterMenuSpan" class="input-append block-div-2">
+ <label for="filter_study_select">Filter samples by study: </label>
+ <select id="filter_study">
+ {% for study in study_samplelists %}
+ <option value="{{ loop.index - 1 }}">{{ study }}</option>
+ {% endfor %}
+ </select>
+ {% if sample_groups|length != 1 %}
+ <select id="filter_study_group" size="1">
+ <option value="primary">
+ {{ sample_group_types['samples_primary'] }}
+ </option>
+ <option value="other">
+ {{ sample_group_types['samples_other'] }}
+ </option>
+ </select>
+ {% endif %}
+ <input type="button" id="filter_by_study" class="btn btn-danger" value="Filter">
+ </div>
+ {% endif %}
<div id="filterMenuSpan" class="input-append block-div-2">
<label for="filter_samples_field">Filter samples by {% if (numerical_var_list|length == 0) and (not js_data.se_exists) %}value{% endif %} </label>
{% if (numerical_var_list|length > 0) or js_data.se_exists %}
@@ -53,10 +74,12 @@
{% if js_data.se_exists %}
<option value="stderr">SE</option>
{% endif %}
- {% for attribute in numerical_var_list %}
+ {% for attribute in sample_groups[0].attributes %}
+ {% if sample_groups[0].attributes[attribute].name in numerical_var_list %}
<option value="{{ loop.index }}">
- {{ attribute }}
+ {{ sample_groups[0].attributes[attribute].name }}
</option>
+ {% endif %}
{% endfor %}
</select>
{% endif %}
diff --git a/wqflask/wqflask/templates/test_correlation_page.html b/wqflask/wqflask/templates/test_correlation_page.html
index 0809b65e..991773a2 100644
--- a/wqflask/wqflask/templates/test_correlation_page.html
+++ b/wqflask/wqflask/templates/test_correlation_page.html
@@ -113,7 +113,7 @@ console.log(correlationResults)
{"data":corr_type=="sample"?null:"fd","width":"25px"},
{ "data": "index","width":"120px","title":"Index" },
{ "data": "trait_name","title":"TraitName"},
- { "data": "corr_coeffient","defaultContent": "--"},
+ { "data": "corr_coefficient","defaultContent": "--"},
{ "data": "p_value","defaultContent":"--"},
{ "data": "num_overlap","defaultContent":"--"},
{"data":"tissue_corr","defaultContent":"--","title":"Tissue r"},
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index b9181368..5067ca0e 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -27,6 +27,8 @@ from zipfile import ZIP_DEFLATED
from wqflask import app
+from gn3.commands import run_cmd
+from gn3.computations.gemma import generate_hash_of_string
from gn3.db import diff_from_dict
from gn3.db import fetchall
from gn3.db import fetchone
@@ -34,12 +36,17 @@ from gn3.db import insert
from gn3.db import update
from gn3.db.metadata_audit import MetadataAudit
from gn3.db.phenotypes import Phenotype
+from gn3.db.phenotypes import Probeset
from gn3.db.phenotypes import Publication
from gn3.db.phenotypes import PublishXRef
+from gn3.db.phenotypes import probeset_mapping
+from gn3.db.traits import get_trait_csv_sample_data
+from gn3.db.traits import update_sample_data
from flask import current_app
from flask import g
+from flask import flash
from flask import Response
from flask import request
from flask import make_response
@@ -57,6 +64,7 @@ from wqflask import server_side
from base.data_set import create_dataset # Used by YAML in marker_regression
from wqflask.show_trait import show_trait
from wqflask.show_trait import export_trait_data
+from wqflask.show_trait.show_trait import get_diff_of_vals
from wqflask.heatmap import heatmap
from wqflask.external_tools import send_to_bnw
from wqflask.external_tools import send_to_webgestalt
@@ -65,7 +73,7 @@ from wqflask.comparison_bar_chart import comparison_bar_chart
from wqflask.marker_regression import run_mapping
from wqflask.marker_regression import display_mapping_results
from wqflask.network_graph import network_graph
-from wqflask.correlation import show_corr_results
+from wqflask.correlation.show_corr_results import set_template_vars
from wqflask.correlation.correlation_gn3_api import compute_correlation
from wqflask.correlation_matrix import show_corr_matrix
from wqflask.correlation import corr_scatter_plot
@@ -77,7 +85,7 @@ from wqflask.export_traits import export_search_results_csv
from wqflask.gsearch import GSearch
from wqflask.update_search_results import GSearch as UpdateGSearch
from wqflask.docs import Docs, update_text
-from wqflask.decorators import admin_login_required
+from wqflask.decorators import edit_access_required
from wqflask.db_info import InfoPage
from utility import temp_data
@@ -152,28 +160,37 @@ def shutdown_session(exception=None):
@app.errorhandler(Exception)
-def handle_bad_request(e):
+def handle_generic_exceptions(e):
+ import werkzeug
err_msg = str(e)
- logger.error(err_msg)
- logger.error(request.url)
- # get the stack trace and send it to the logger
- exc_type, exc_value, exc_traceback = sys.exc_info()
- logger.error(traceback.format_exc())
now = datetime.datetime.utcnow()
time_str = now.strftime('%l:%M%p UTC %b %d, %Y')
- formatted_lines = [request.url
- + " (" + time_str + ")"] + traceback.format_exc().splitlines()
-
+ # get the stack trace and send it to the logger
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ formatted_lines = {f"{request.url} ({time_str}) "
+ f" {traceback.format_exc().splitlines()}"}
+
+ _message_templates = {
+ werkzeug.exceptions.NotFound: ("404: Not Found: "
+ f"{time_str}: {request.url}"),
+ werkzeug.exceptions.BadRequest: ("400: Bad Request: "
+ f"{time_str}: {request.url}"),
+ werkzeug.exceptions.RequestTimeout: ("408: Request Timeout: "
+ f"{time_str}: {request.url}")}
+ # Default to the lengthy stack trace!
+ logger.error(_message_templates.get(exc_type,
+ formatted_lines))
# Handle random animations
# Use a cookie to have one animation on refresh
animation = request.cookies.get(err_msg[:32])
if not animation:
- list = [fn for fn in os.listdir(
- "./wqflask/static/gif/error") if fn.endswith(".gif")]
- animation = random.choice(list)
+ animation = random.choice([fn for fn in os.listdir(
+ "./wqflask/static/gif/error") if fn.endswith(".gif")])
resp = make_response(render_template("error.html", message=err_msg,
- stack=formatted_lines, error_image=animation, version=GN_VERSION))
+ stack=formatted_lines,
+ error_image=animation,
+ version=GN_VERSION))
# logger.error("Set cookie %s with %s" % (err_msg, animation))
resp.set_cookie(err_msg[:32], animation)
@@ -300,6 +317,7 @@ def gsearchact():
elif type == "phenotype":
return render_template("gsearch_pheno.html", **result)
+
@app.route("/gsearch_table", methods=('GET',))
def gsearchtable():
logger.info(request.url)
@@ -314,6 +332,7 @@ def gsearchtable():
return flask.jsonify(current_page)
+
@app.route("/gsearch_updating", methods=('POST',))
def gsearch_updating():
logger.info("REQUEST ARGS:", request.values)
@@ -357,20 +376,6 @@ def wcgna_setup():
return render_template("wgcna_setup.html", **request.form)
-# @app.route("/wgcna_results", methods=('POST',))
-# def wcgna_results():
-# logger.info("In wgcna, request.form is:", request.form)
-# logger.info(request.url)
-# # Start R, load the package and pointers and create the analysis
-# wgcna = wgcna_analysis.WGCNA()
-# # Start the analysis, a wgcnaA object should be a separate long running thread
-# wgcnaA = wgcna.run_analysis(request.form)
-# # After the analysis is finished store the result
-# result = wgcna.process_results(wgcnaA)
-# # Display them using the template
-# return render_template("wgcna_results.html", **result)
-
-
@app.route("/ctl_setup", methods=('POST',))
def ctl_setup():
# We are going to get additional user input for the analysis
@@ -380,20 +385,6 @@ def ctl_setup():
return render_template("ctl_setup.html", **request.form)
-# @app.route("/ctl_results", methods=('POST',))
-# def ctl_results():
-# logger.info("In ctl, request.form is:", request.form)
-# logger.info(request.url)
-# # Start R, load the package and pointers and create the analysis
-# ctl = ctl_analysis.CTL()
-# # Start the analysis, a ctlA object should be a separate long running thread
-# ctlA = ctl.run_analysis(request.form)
-# # After the analysis is finished store the result
-# result = ctl.process_results(ctlA)
-# # Display them using the template
-# return render_template("ctl_results.html", **result)
-
-
@app.route("/intro")
def intro():
doc = Docs("intro", request.args)
@@ -428,9 +419,9 @@ def submit_trait_form():
version=GN_VERSION)
-@app.route("/trait/<name>/edit/<inbred_set_id>")
-@admin_login_required
-def edit_trait(name, inbred_set_id):
+@app.route("/trait/<name>/edit/inbredset-id/<inbredset_id>")
+@edit_access_required
+def edit_phenotype(name, inbredset_id):
conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
user=current_app.config.get("DB_USER"),
passwd=current_app.config.get("DB_PASS"),
@@ -439,7 +430,7 @@ def edit_trait(name, inbred_set_id):
conn=conn,
table="PublishXRef",
where=PublishXRef(id_=name,
- inbred_set_id=inbred_set_id))
+ inbred_set_id=inbredset_id))
phenotype_ = fetchone(
conn=conn,
table="Phenotype",
@@ -476,7 +467,7 @@ def edit_trait(name, inbred_set_id):
if len(diff_data) > 0:
diff_data_ = groupby(diff_data, lambda x: x.timestamp)
return render_template(
- "edit_trait.html",
+ "edit_phenotype.html",
diff=diff_data_,
publish_xref=publish_xref,
phenotype=phenotype_,
@@ -485,13 +476,119 @@ def edit_trait(name, inbred_set_id):
)
+@app.route("/trait/edit/probeset-name/<dataset_name>")
+@edit_access_required
+def edit_probeset(dataset_name):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ probeset_ = fetchone(conn=conn,
+ table="ProbeSet",
+ columns=list(probeset_mapping.values()),
+ where=Probeset(name=dataset_name))
+ json_data = fetchall(
+ conn,
+ "metadata_audit",
+ where=MetadataAudit(dataset_id=probeset_.id_))
+ Edit = namedtuple("Edit", ["field", "old", "new", "diff"])
+ Diff = namedtuple("Diff", ["author", "diff", "timestamp"])
+ diff_data = []
+ for data in json_data:
+ json_ = json.loads(data.json_data)
+ timestamp = json_.get("timestamp")
+ author = json_.get("author")
+ for key, value in json_.items():
+ if isinstance(value, dict):
+ for field, data_ in value.items():
+ diff_data.append(
+ Diff(author=author,
+ diff=Edit(field,
+ data_.get("old"),
+ data_.get("new"),
+ "\n".join(difflib.ndiff(
+ [data_.get("old")],
+ [data_.get("new")]))),
+ timestamp=timestamp))
+ diff_data_ = None
+ if len(diff_data) > 0:
+ diff_data_ = groupby(diff_data, lambda x: x.timestamp)
+ return render_template(
+ "edit_probeset.html",
+ diff=diff_data_,
+ probeset=probeset_)
+
+
@app.route("/trait/update", methods=["POST"])
-def update_trait():
+@edit_access_required
+def update_phenotype():
conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
user=current_app.config.get("DB_USER"),
passwd=current_app.config.get("DB_PASS"),
host=current_app.config.get("DB_HOST"))
data_ = request.form.to_dict()
+ TMPDIR = current_app.config.get("TMPDIR")
+ author = g.user_session.record.get(b'user_name')
+ if 'file' not in request.files:
+ flash("No sample-data has been uploaded", "warning")
+ else:
+ file_ = request.files['file']
+ trait_name = str(data_.get('dataset-name'))
+ phenotype_id = str(data_.get('phenotype-id', 35))
+ SAMPLE_DATADIR = os.path.join(TMPDIR, "sample-data")
+ if not os.path.exists(SAMPLE_DATADIR):
+ os.makedirs(SAMPLE_DATADIR)
+ if not os.path.exists(os.path.join(SAMPLE_DATADIR,
+ "diffs")):
+ os.makedirs(os.path.join(SAMPLE_DATADIR,
+ "diffs"))
+ if not os.path.exists(os.path.join(SAMPLE_DATADIR,
+ "updated")):
+ os.makedirs(os.path.join(SAMPLE_DATADIR,
+ "updated"))
+ current_time = str(datetime.datetime.now().isoformat())
+ new_file_name = (os.path.join(TMPDIR,
+ "sample-data/updated/",
+ (f"{author.decode('utf-8')}."
+ f"{trait_name}.{phenotype_id}."
+ f"{current_time}.csv")))
+ uploaded_file_name = (os.path.join(
+ TMPDIR,
+ "sample-data/updated/",
+ (f"updated.{author.decode('utf-8')}."
+ f"{trait_name}.{phenotype_id}."
+ f"{current_time}.csv")))
+ file_.save(new_file_name)
+ publishdata_id = ""
+ lines = []
+ with open(new_file_name, "r") as f:
+ lines = f.read()
+ first_line = lines.split('\n', 1)[0]
+ publishdata_id = first_line.split("Id:")[-1].strip()
+ with open(new_file_name, "w") as f:
+ f.write(lines.split("\n\n")[-1])
+ csv_ = get_trait_csv_sample_data(conn=conn,
+ trait_name=str(trait_name),
+ phenotype_id=str(phenotype_id))
+ with open(uploaded_file_name, "w") as f_:
+ f_.write(csv_.split("\n\n")[-1])
+ r = run_cmd(cmd=("csvdiff "
+ f"'{uploaded_file_name}' '{new_file_name}' "
+ "--format json"))
+ diff_output = (f"{TMPDIR}/sample-data/diffs/"
+ f"{trait_name}.{author.decode('utf-8')}."
+ f"{phenotype_id}.{current_time}.json")
+ with open(diff_output, "w") as f:
+ dict_ = json.loads(r.get("output"))
+ dict_.update({
+ "author": author.decode('utf-8'),
+ "publishdata_id": publishdata_id,
+ "dataset_id": data_.get("dataset-name"),
+ "timestamp": datetime.datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S")
+ })
+ f.write(json.dumps(dict_))
+ flash("Sample-data has been successfully uploaded", "success")
# Run updates:
phenotype_ = {
"pre_pub_description": data_.get("pre-pub-desc"),
@@ -533,7 +630,6 @@ def update_trait():
diff_data.update({"Publication": diff_from_dict(old={
k: data_.get(f"old_{k}") for k, v in publication_.items()
if v is not None}, new=publication_)})
- author = g.user_session.record.get(b'user_name')
if diff_data:
diff_data.update({"dataset_id": data_.get("dataset-name")})
diff_data.update({"author": author.decode('utf-8')})
@@ -544,7 +640,66 @@ def update_trait():
data=MetadataAudit(dataset_id=data_.get("dataset-name"),
editor=author.decode("utf-8"),
json_data=json.dumps(diff_data)))
- return redirect("/trait/10007/edit/1")
+ flash(f"Diff-data: \n{diff_data}\nhas been uploaded", "success")
+ return redirect(f"/trait/{data_.get('dataset-name')}"
+ f"/edit/inbredset-id/{data_.get('inbred-set-id')}")
+
+
+@app.route("/probeset/update", methods=["POST"])
+@edit_access_required
+def update_probeset():
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ data_ = request.form.to_dict()
+ probeset_ = {
+ "id_": data_.get("id"),
+ "symbol": data_.get("symbol"),
+ "description": data_.get("description"),
+ "probe_target_description": data_.get("probe_target_description"),
+ "chr_": data_.get("chr"),
+ "mb": data_.get("mb"),
+ "alias": data_.get("alias"),
+ "geneid": data_.get("geneid"),
+ "homologeneid": data_.get("homologeneid"),
+ "unigeneid": data_.get("unigeneid"),
+ "omim": data_.get("OMIM"),
+ "refseq_transcriptid": data_.get("refseq_transcriptid"),
+ "blatseq": data_.get("blatseq"),
+ "targetseq": data_.get("targetseq"),
+ "strand_probe": data_.get("Strand_Probe"),
+ "probe_set_target_region": data_.get("probe_set_target_region"),
+ "probe_set_specificity": data_.get("probe_set_specificity"),
+ "probe_set_blat_score": data_.get("probe_set_blat_score"),
+ "probe_set_blat_mb_start": data_.get("probe_set_blat_mb_start"),
+ "probe_set_blat_mb_end": data_.get("probe_set_blat_mb_end"),
+ "probe_set_strand": data_.get("probe_set_strand"),
+ "probe_set_note_by_rw": data_.get("probe_set_note_by_rw"),
+ "flag": data_.get("flag")
+ }
+ updated_probeset = update(
+ conn, "ProbeSet",
+ data=Probeset(**probeset_),
+ where=Probeset(id_=data_.get("id")))
+
+ diff_data = {}
+ author = g.user_session.record.get(b'user_name')
+ if updated_probeset:
+ diff_data.update({"Probeset": diff_from_dict(old={
+ k: data_.get(f"old_{k}") for k, v in probeset_.items()
+ if v is not None}, new=probeset_)})
+ if diff_data:
+ diff_data.update({"probeset_name": data_.get("probeset_name")})
+ diff_data.update({"author": author.decode('utf-8')})
+ diff_data.update({"timestamp": datetime.datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S")})
+ insert(conn,
+ table="metadata_audit",
+ data=MetadataAudit(dataset_id=data_.get("id"),
+ editor=author.decode("utf-8"),
+ json_data=json.dumps(diff_data)))
+ return redirect(f"/trait/edit/probeset-name/{data_.get('probeset_name')}")
@app.route("/create_temp_trait", methods=('POST',))
@@ -852,16 +1007,16 @@ def loading_page():
if key in wanted:
start_vars[key] = value
+ sample_vals_dict = json.loads(start_vars['sample_vals'])
if 'n_samples' in start_vars:
n_samples = int(start_vars['n_samples'])
else:
- sample_vals_dict = json.loads(start_vars['sample_vals'])
if 'group' in start_vars:
dataset = create_dataset(
start_vars['dataset'], group_name=start_vars['group'])
else:
dataset = create_dataset(start_vars['dataset'])
- samples = start_vars['primary_samples'].split(",")
+ samples = dataset.group.samplelist
if 'genofile' in start_vars:
if start_vars['genofile'] != "":
genofile_string = start_vars['genofile']
@@ -877,6 +1032,10 @@ def loading_page():
n_samples += 1
start_vars['n_samples'] = n_samples
+ start_vars['vals_hash'] = generate_hash_of_string(str(sample_vals_dict))
+ if start_vars['dataset'] != "Temp": # Currently can't get diff for temp traits
+ start_vars['vals_diff'] = get_diff_of_vals(sample_vals_dict, str(start_vars['trait_id'] + ":" + str(start_vars['dataset'])))
+
start_vars['wanted_inputs'] = initial_start_vars['wanted_inputs']
start_vars_container['start_vars'] = start_vars
@@ -901,6 +1060,7 @@ def mapping_results_page():
'samples',
'vals',
'sample_vals',
+ 'vals_hash',
'first_run',
'output_files',
'geno_db_exists',
@@ -917,7 +1077,6 @@ def mapping_results_page():
'num_perm',
'permCheck',
'perm_strata',
- 'strat_var',
'categorical_vars',
'perm_output',
'num_bootstrap',
@@ -947,7 +1106,6 @@ def mapping_results_page():
'mapmethod_rqtl_geno',
'mapmodel_rqtl_geno',
'temp_trait',
- 'reaper_version',
'n_samples',
'transform'
)
@@ -1006,9 +1164,8 @@ def mapping_results_page():
gn1_template_vars = display_mapping_results.DisplayMappingResults(
result).__dict__
- with Bench("Rendering template"):
- rendered_template = render_template(
- "mapping_results.html", **gn1_template_vars)
+ rendered_template = render_template(
+ "mapping_results.html", **gn1_template_vars)
return rendered_template
@@ -1021,7 +1178,7 @@ def export_mapping_results():
results_csv = open(file_path, "r").read()
response = Response(results_csv,
mimetype='text/csv',
- headers={"Content-Disposition": "attachment;filename=mapping_results.csv"})
+ headers={"Content-Disposition": "attachment;filename=" + os.path.basename(file_path)})
return response
@@ -1082,22 +1239,17 @@ def network_graph_page():
@app.route("/corr_compute", methods=('POST',))
def corr_compute_page():
- logger.info("In corr_compute, request.form is:", pf(request.form))
- logger.info(request.url)
- template_vars = show_corr_results.CorrelationResults(request.form)
- return render_template("correlation_page.html", **template_vars.__dict__)
-
- # to test/disable the new correlation api uncomment these lines
-
- # correlation_results = compute_correlation(request.form)
- # return render_template("test_correlation_page.html", correlation_results=correlation_results)
+ correlation_results = compute_correlation(request.form, compute_all=True)
+ correlation_results = set_template_vars(request.form, correlation_results)
+ return render_template("correlation_page.html", **correlation_results)
@app.route("/test_corr_compute", methods=["POST"])
def test_corr_compute_page():
- correlation_data = compute_correlation(request.form)
+ correlation_data = compute_correlation(request.form, compute_all=True)
return render_template("test_correlation_page.html", **correlation_data)
-
+
+
@app.route("/corr_matrix", methods=('POST',))
def corr_matrix_page():
logger.info("In corr_matrix, request.form is:", pf(request.form))
@@ -1195,8 +1347,6 @@ def browser_inputs():
return flask.jsonify(file_contents)
-##########################################################################
-
def json_default_handler(obj):
"""Based on http://stackoverflow.com/a/2680060/1175849"""
@@ -1212,3 +1362,112 @@ def json_default_handler(obj):
else:
raise TypeError('Object of type %s with value of %s is not JSON serializable' % (
type(obj), repr(obj)))
+
+
+@app.route("/trait/<trait_name>/sampledata/<phenotype_id>")
+def get_sample_data_as_csv(trait_name: int, phenotype_id: int):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ csv_ = get_trait_csv_sample_data(conn, str(trait_name),
+ str(phenotype_id))
+ return Response(
+ csv_,
+ mimetype="text/csv",
+ headers={"Content-disposition":
+ "attachment; filename=myplot.csv"}
+ )
+
+
+@app.route("/admin/data-sample/diffs/")
+@edit_access_required
+def display_diffs_admin():
+ TMPDIR = current_app.config.get("TMPDIR")
+ DIFF_DIR = f"{TMPDIR}/sample-data/diffs"
+ files = []
+ if os.path.exists(DIFF_DIR):
+ files = os.listdir(DIFF_DIR)
+ files = filter(lambda x: not(x.endswith((".approved", ".rejected"))),
+ files)
+ return render_template("display_files_admin.html",
+ files=files)
+
+
+@app.route("/user/data-sample/diffs/")
+def display_diffs_users():
+ TMPDIR = current_app.config.get("TMPDIR")
+ DIFF_DIR = f"{TMPDIR}/sample-data/diffs"
+ files = []
+ author = g.user_session.record.get(b'user_name').decode("utf-8")
+ if os.path.exists(DIFF_DIR):
+ files = os.listdir(DIFF_DIR)
+ files = filter(lambda x: not(x.endswith((".approved", ".rejected"))) \
+ and author in x,
+ files)
+ return render_template("display_files_user.html",
+ files=files)
+
+
+@app.route("/data-samples/approve/<name>")
+def approve_data(name):
+ sample_data = {}
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ TMPDIR = current_app.config.get("TMPDIR")
+ with open(os.path.join(f"{TMPDIR}/sample-data/diffs",
+ name), 'r') as myfile:
+ sample_data = json.load(myfile)
+ PUBLISH_ID = sample_data.get("publishdata_id")
+ modifications = [d for d in sample_data.get("Modifications")]
+ row_counts = len(modifications)
+ for modification in modifications:
+ if modification.get("Current"):
+ (strain_id,
+ strain_name,
+ value, se, count) = modification.get("Current").split(",")
+ update_sample_data(
+ conn=conn,
+ strain_name=strain_name,
+ strain_id=int(strain_id),
+ publish_data_id=int(PUBLISH_ID),
+ value=value,
+ error=se,
+ count=count
+ )
+ insert(conn,
+ table="metadata_audit",
+ data=MetadataAudit(
+ dataset_id=name.split(".")[0], # use the dataset name
+ editor=sample_data.get("author"),
+ json_data=json.dumps(sample_data)))
+ if modifications:
+ # Once data is approved, rename it!
+ os.rename(os.path.join(f"{TMPDIR}/sample-data/diffs", name),
+ os.path.join(f"{TMPDIR}/sample-data/diffs",
+ f"{name}.approved"))
+ flash((f"Just updated data from: {name}; {row_counts} "
+ "row(s) modified!"),
+ "success")
+ return redirect("/admin/data-sample/diffs/")
+
+
+@app.route("/data-samples/reject/<name>")
+def reject_data(name):
+ TMPDIR = current_app.config.get("TMPDIR")
+ os.rename(os.path.join(f"{TMPDIR}/sample-data/diffs", name),
+ os.path.join(f"{TMPDIR}/sample-data/diffs",
+ f"{name}.rejected"))
+ flash(f"{name} has been rejected!", "success")
+ return redirect("/admin/data-sample/diffs/")
+
+
+@app.route("/display-file/<name>")
+def display_file(name):
+ TMPDIR = current_app.config.get("TMPDIR")
+ with open(os.path.join(f"{TMPDIR}/sample-data/diffs",
+ name), 'r') as myfile:
+ content = myfile.read()
+ return Response(content, mimetype='text/json')