diff options
66 files changed, 1730 insertions, 2139 deletions
@@ -5,6 +5,7 @@ *~ *.swo *.swp +containers/mariadb-state genotype_files/genotype/HSNIH_copy.geno web/new_genotypes/HSNIH.json wqflask/secure_server.py @@ -84,7 +84,7 @@ use `GN3_PYTHONPATH` environment that gets injected in the ./bin/genenetwork2 startup. A continuously deployed instance of genenetwork2 is available at -[https://gn2dev.genenetwork.org/](https://gn2dev.genenetwork.org/). This +[https://cd.genenetwork.org/](https://cd.genenetwork.org/). This instance is redeployed on every commit provided that the [continuous integration tests](https://ci.genenetwork.org/jobs/genenetwork2) pass. diff --git a/containers/db-container.scm b/containers/db-container.scm new file mode 100644 index 00000000..848b6a2e --- /dev/null +++ b/containers/db-container.scm @@ -0,0 +1,38 @@ +;;; This file describes a Guix system container to run the database +;;; services required by genenetwork2 locally on your own +;;; machine. This is to allow a purely offline development setup for +;;; hacking on genenetwork2. To build and run the container, use +;;; db-container.sh. + +(use-modules (gnu) + (gnu packages databases) + (gnu services databases)) + +(define %mariadb-state-directory + "/var/lib/mysql") + +(define set-permissions-gexp + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils)) + + ;; Set ownership of mariadb state directory. + (let ((user (getpw "mysql"))) + (for-each (lambda (file) + (chown file (passwd:uid user) (passwd:gid user))) + (find-files #$%mariadb-state-directory #:directories? #t)))))) + +(operating-system + (host-name "genenetwork2") + (timezone "Etc/UTC") + (locale "en_US.utf8") + (bootloader (bootloader-configuration + (bootloader grub-bootloader) + (targets (list "does-not-matter")))) + (file-systems %base-file-systems) + (services (cons* (service mysql-service-type) + (service redis-service-type) + (simple-service 'set-permissions + activation-service-type + set-permissions-gexp) + %base-services))) diff --git a/containers/db-container.sh b/containers/db-container.sh new file mode 100755 index 00000000..bbe0247a --- /dev/null +++ b/containers/db-container.sh @@ -0,0 +1,12 @@ +#! /bin/sh -e + +# Find path to containers directory. +containers=$(dirname $0) + +# Create mariadb state directory if it does not exist. +mkdir -p $containers/mariadb-state + +# Build the container. +guix system container --network \ + --share=$containers/mariadb-state=/var/lib/mysql \ + $containers/db-container.scm diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 72906515..2f4c1154 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -21,10 +21,7 @@ from dataclasses import dataclass from dataclasses import field from dataclasses import InitVar from typing import Optional, Dict, List -from db.call import fetchall, fetchone, fetch1 -from utility.logger import getLogger from utility.tools import USE_GN_SERVER, USE_REDIS, flat_files, flat_file_exists, GN2_BASE_URL -from db.gn_server import menu_main from pprint import pformat as pf from utility.db_tools import escape from utility.db_tools import mescape @@ -33,7 +30,6 @@ from maintenance import get_group_samplelists from utility.tools import locate, locate_ignore_error, flat_files from utility import gen_geno_ob from utility import chunks -from utility.benchmark import Bench from utility import webqtlUtil from db import webqtlDatabaseFunction from base import species @@ -42,6 +38,7 @@ from flask import Flask, g from base.webqtlConfig import TMPDIR from urllib.parse import urlparse from utility.tools import SQL_URI +from wqflask.database import database_connection import os import math import string @@ -60,8 +57,6 @@ from redis import Redis r = Redis() -logger = getLogger(__name__) - # Used by create_database to instantiate objects # Each subclass will add to this DS_NAME_MAP = {} @@ -200,26 +195,23 @@ def create_datasets_list(): result = r.get(key) if result: - logger.debug("Redis cache hit") datasets = pickle.loads(result) if result is None: datasets = list() - with Bench("Creating DataSets object"): - type_dict = {'Publish': 'PublishFreeze', - 'ProbeSet': 'ProbeSetFreeze', - 'Geno': 'GenoFreeze'} - - for dataset_type in type_dict: - query = "SELECT Name FROM {}".format(type_dict[dataset_type]) - for result in fetchall(query): - # The query at the beginning of this function isn't - # necessary here, but still would rather just reuse - # it logger.debug("type: {}\tname: - # {}".format(dataset_type, result.Name)) - dataset = create_dataset(result.Name, dataset_type) - datasets.append(dataset) - + type_dict = {'Publish': 'PublishFreeze', + 'ProbeSet': 'ProbeSetFreeze', + 'Geno': 'GenoFreeze'} + + for dataset_type in type_dict: + with database_connection() as conn, conn.cursor() as cursor: + cursor.execute("SELECT Name FROM %s", + (type_dict[dataset_type],)) + results = cursor.fetchall(query) + if results: + for result in results: + datasets.append( + create_dataset(result.Name, dataset_type)) if USE_REDIS: r.set(key, pickle.dumps(datasets, pickle.HIGHEST_PROTOCOL)) r.expire(key, 60 * 60) @@ -259,9 +251,6 @@ class Markers: self.markers = markers def add_pvalues(self, p_values): - logger.debug("length of self.markers:", len(self.markers)) - logger.debug("length of p_values:", len(p_values)) - if isinstance(p_values, list): # THIS IS only needed for the case when we are limiting the number of p-values calculated # if len(self.markers) > len(p_values): @@ -332,12 +321,16 @@ class DatasetGroup: def __init__(self, dataset, name=None): """This sets self.group and self.group_id""" - if name == None: - self.name, self.id, self.genetic_type, self.code = fetchone( - dataset.query_for_group) - else: - self.name, self.id, self.genetic_type, self.code = fetchone( - "SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode FROM InbredSet where Name='%s'" % name) + query = """SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, + InbredSet.InbredSetCode FROM InbredSet where Name=%s + """ + if not name: + query, name = dataset.query_for_group, dataset.name + with database_connection() as conn, conn.cursor() as cursor: + cursor.execute(query, (name,)) + results = cursor.fetchone() + if results: + self.name, self.id, self.genetic_type, self.code = results if self.name == 'BXD300': self.name = "BXD" @@ -483,28 +476,28 @@ class DatasetGroup: def datasets(group_name, this_group=None): key = "group_dataset_menu:v2:" + group_name dataset_menu = [] - the_results = fetchall(''' - (SELECT '#PublishFreeze',PublishFreeze.FullName,PublishFreeze.Name - FROM PublishFreeze,InbredSet - WHERE PublishFreeze.InbredSetId = InbredSet.Id + the_results = g.db.execute(''' + (SELECT '#PublishFreeze',PublishFreeze.FullName,PublishFreeze.Name + FROM PublishFreeze,InbredSet + WHERE PublishFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = '%s' - ORDER BY PublishFreeze.Id ASC) - UNION - (SELECT '#GenoFreeze',GenoFreeze.FullName,GenoFreeze.Name - FROM GenoFreeze, InbredSet - WHERE GenoFreeze.InbredSetId = InbredSet.Id + ORDER BY PublishFreeze.Id ASC) + UNION + (SELECT '#GenoFreeze',GenoFreeze.FullName,GenoFreeze.Name + FROM GenoFreeze, InbredSet + WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = '%s') - UNION - (SELECT Tissue.Name, ProbeSetFreeze.FullName,ProbeSetFreeze.Name - FROM ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue - WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id + UNION + (SELECT Tissue.Name, ProbeSetFreeze.FullName,ProbeSetFreeze.Name + FROM ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue + WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like %s - ORDER BY Tissue.Name, ProbeSetFreeze.OrderList DESC) + ORDER BY Tissue.Name, ProbeSetFreeze.OrderList DESC) ''' % (group_name, - group_name, - "'" + group_name + "'")) + group_name, + "'" + group_name + "'")).fetchall() sorted_results = sorted(the_results, key=lambda kv: kv[0]) @@ -633,39 +626,33 @@ class DataSet: """ try: + query = "" + _vars = None + query_args = (self.name, self.name, self.name) if self.type == "ProbeSet": - query_args = tuple(escape(x) for x in ( - self.name, - self.name, - self.name)) - - self.id, self.name, self.fullname, self.shortname, self.data_scale, self.tissue = fetch1(""" - SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.FullName, ProbeSetFreeze.ShortName, ProbeSetFreeze.DataScale, Tissue.Name - FROM ProbeSetFreeze, ProbeFreeze, Tissue - WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id - AND ProbeFreeze.TissueId = Tissue.Id - AND (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFreeze.ShortName = '%s') - """ % (query_args), "/dataset/" + self.name + ".json", - lambda r: (r["id"], r["name"], r["full_name"], - r["short_name"], r["data_scale"], r["tissue"]) - ) + query = ( + "SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, " + "ProbeSetFreeze.FullName, ProbeSetFreeze.ShortName, " + "ProbeSetFreeze.DataScale, Tissue.Name " + "FROM ProbeSetFreeze, ProbeFreeze, Tissue " + "WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id " + "AND ProbeFreeze.TissueId = Tissue.Id " + "AND (ProbeSetFreeze.Name = %s OR ProbeSetFreeze.FullName = %s OR ProbeSetFreeze.ShortName = %s)") else: - query_args = tuple(escape(x) for x in ( - (self.type + "Freeze"), - self.name, - self.name, - self.name)) - + query = ( + "SELECT Id, Name, FullName, ShortName " + f"FROM {self.type}Freeze " + "WHERE (Name = %s OR FullName = %s OR ShortName = %s)") self.tissue = "N/A" - self.id, self.name, self.fullname, self.shortname = fetchone(""" - SELECT Id, Name, FullName, ShortName - FROM %s - WHERE (Name = '%s' OR FullName = '%s' OR ShortName = '%s') - """ % (query_args)) - + with database_connection() as conn, conn.cursor() as cursor: + cursor.execute(query, query_args) + _vars = cursor.fetchone() + if self.type == "ProbeSet": + (self.id, self.name, self.fullname, self.shortname, + self.data_scale, self.tissue) = _vars + else: + self.id, self.name, self.fullname, self.shortname = _vars except TypeError: - logger.debug( - "Dataset {} is not yet available in GeneNetwork.".format(self.name)) pass def chunk_dataset(self, dataset, n): @@ -863,16 +850,8 @@ class PhenotypeDataSet(DataSet): 'Additive Effect'] self.type = 'Publish' - - self.query_for_group = ''' - SELECT - InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode - FROM - InbredSet, PublishFreeze - WHERE - PublishFreeze.InbredSetId = InbredSet.Id AND - PublishFreeze.Name = "%s" - ''' % escape(self.name) + self.query_for_group = """ +SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode FROM InbredSet, PublishFreeze WHERE PublishFreeze.InbredSetId = InbredSet.Id AND PublishFreeze.Name = %s""" def check_confidentiality(self): # (Urgently?) Need to write this @@ -979,16 +958,10 @@ class GenotypeDataSet(DataSet): # Todo: Obsolete or rename this field self.type = 'Geno' - - self.query_for_group = ''' - SELECT - InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode - FROM - InbredSet, GenoFreeze - WHERE - GenoFreeze.InbredSetId = InbredSet.Id AND - GenoFreeze.Name = "%s" - ''' % escape(self.name) + self.query_for_group = """ +SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode +FROM InbredSet, GenoFreeze WHERE GenoFreeze.InbredSetId = InbredSet.Id AND +GenoFreeze.Name = %s""" def check_confidentiality(self): return geno_mrna_confidentiality(self) @@ -1087,17 +1060,10 @@ class MrnaAssayDataSet(DataSet): # Todo: Obsolete or rename this field self.type = 'ProbeSet' - - self.query_for_group = ''' - SELECT - InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode - FROM - InbredSet, ProbeSetFreeze, ProbeFreeze - WHERE - ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % escape(self.name) + self.query_for_group = """ +SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType, InbredSet.InbredSetCode +FROM InbredSet, ProbeSetFreeze, ProbeFreeze WHERE ProbeFreeze.InbredSetId = InbredSet.Id AND +ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND ProbeSetFreeze.Name = %s""" def check_confidentiality(self): return geno_mrna_confidentiality(self) diff --git a/wqflask/base/mrna_assay_tissue_data.py b/wqflask/base/mrna_assay_tissue_data.py index 8f8e2b0a..d7e747aa 100644 --- a/wqflask/base/mrna_assay_tissue_data.py +++ b/wqflask/base/mrna_assay_tissue_data.py @@ -9,10 +9,6 @@ from utility.db_tools import escape from gn3.db_utils import database_connector -from utility.logger import getLogger -logger = getLogger(__name__) - - class MrnaAssayTissueData: def __init__(self, gene_symbols=None): diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 11b28c5c..b02c6033 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -300,10 +300,16 @@ def jsonable(trait, dataset=None): dataset_type=trait.dataset.type, group_name=trait.dataset.group.name) + trait_symbol = "N/A" + if trait.symbol: + trait_symbol = trait.symbol + if dataset.type == "ProbeSet": return dict(name=trait.name, - view=trait.view, - symbol=trait.symbol, + display_name=trait.display_name, + hmac=hmac.data_hmac('{}:{}'.format(trait.display_name, dataset.name)), + view=str(trait.view), + symbol=trait_symbol, dataset=dataset.name, dataset_name=dataset.shortname, description=trait.description_display, @@ -316,7 +322,10 @@ def jsonable(trait, dataset=None): elif dataset.type == "Publish": if trait.pubmed_id: return dict(name=trait.name, - view=trait.view, + display_name=trait.display_name, + hmac=hmac.data_hmac('{}:{}'.format(trait.display_name, dataset.name)), + view=str(trait.view), + symbol=trait_symbol, dataset=dataset.name, dataset_name=dataset.shortname, description=trait.description_display, @@ -332,7 +341,10 @@ def jsonable(trait, dataset=None): ) else: return dict(name=trait.name, - view=trait.view, + display_name=trait.display_name, + hmac=hmac.data_hmac('{}:{}'.format(trait.display_name, dataset.name)), + view=str(trait.view), + symbol=trait_symbol, dataset=dataset.name, dataset_name=dataset.shortname, description=trait.description_display, @@ -346,14 +358,18 @@ def jsonable(trait, dataset=None): ) elif dataset.type == "Geno": return dict(name=trait.name, - view=trait.view, + display_name=trait.display_name, + hmac=hmac.data_hmac('{}:{}'.format(trait.display_name, dataset.name)), + view=str(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, + display_name=trait.display_name, + hmac=hmac.data_hmac('{}:{}'.format(trait.display_name, dataset.name)), + view=str(trait.view), dataset="Temp", dataset_name="Temp") else: diff --git a/wqflask/base/webqtlCaseData.py b/wqflask/base/webqtlCaseData.py index 25b6cb8a..dd6fad04 100644 --- a/wqflask/base/webqtlCaseData.py +++ b/wqflask/base/webqtlCaseData.py @@ -21,9 +21,6 @@ # Created by GeneNetwork Core Team 2010/08/10 -from utility.logger import getLogger -logger = getLogger(__name__) - import utility.tools utility.tools.show_settings() diff --git a/wqflask/db/call.py b/wqflask/db/call.py deleted file mode 100644 index 1fe0772b..00000000 --- a/wqflask/db/call.py +++ /dev/null @@ -1,79 +0,0 @@ -# Module for calling the backend - -from flask import g - -import string -try: # Python2 support - import urllib.request - import urllib.error - import urllib.parse -except: - import urllib2 -import json -from utility.tools import USE_GN_SERVER, LOG_SQL, GN_SERVER_URL -from utility.benchmark import Bench - -from utility.logger import getLogger -logger = getLogger(__name__) - -# from inspect import stack - - -def fetch1(query, path=None, func=None): - """Fetch one result as a Tuple using either a SQL query or the URI -path to GN_SERVER (when USE_GN_SERVER is True). Apply func to -GN_SERVER result when set (which should return a Tuple) - - """ - if USE_GN_SERVER and path: - result = gn_server(path) - if func != None: - res2 = func(result) - else: - res2 = result, - if LOG_SQL: - logger.debug("Replaced SQL call", query) - logger.debug(path, res2) - return res2 - else: - return fetchone(query) - - -def fetchone(query): - """Return tuple containing one row by calling SQL directly (the -original fetchone, but with logging) - - """ - with Bench("SQL", LOG_SQL): - def helper(query): - res = g.db.execute(query) - return res.fetchone() - return logger.sql(query, helper) - - -def fetchall(query): - """Return row iterator by calling SQL directly (the -original fetchall, but with logging) - - """ - with Bench("SQL", LOG_SQL): - def helper(query): - res = g.db.execute(query) - return res.fetchall() - return logger.sql(query, helper) - - -def gn_server(path): - """Return JSON record by calling GN_SERVER - - """ - with Bench("GN_SERVER", LOG_SQL): - res = () - try: - res = urllib.request.urlopen(GN_SERVER_URL + path) - except: - res = urllib2.urlopen(GN_SERVER_URL + path) - rest = res.read() - res2 = json.loads(rest) - logger.debug(res2) - return res2 diff --git a/wqflask/db/gn_server.py b/wqflask/db/gn_server.py deleted file mode 100644 index f9b01658..00000000 --- a/wqflask/db/gn_server.py +++ /dev/null @@ -1,10 +0,0 @@ -# Backend query functions (logic) - -from db.call import gn_server - -from utility.logger import getLogger -logger = getLogger(__name__) - - -def menu_main(): - return gn_server("/int/menu/main.json") diff --git a/wqflask/db/webqtlDatabaseFunction.py b/wqflask/db/webqtlDatabaseFunction.py index 9ec650a4..122c546f 100644 --- a/wqflask/db/webqtlDatabaseFunction.py +++ b/wqflask/db/webqtlDatabaseFunction.py @@ -20,19 +20,23 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from db.call import fetch1 +from wqflask.database import database_connection def retrieve_species(group): """Get the species of a group (e.g. returns string "mouse" on "BXD" """ - result = fetch1("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % ( - group), "/cross/" + group + ".json", lambda r: (r["species"],))[0] + with database_connection() as conn, conn.cursor() as cursor: + cursor.execute( + "SELECT Species.Name FROM Species, InbredSet WHERE InbredSet.Name = %s AND InbredSet.SpeciesId = Species.Id", + (group,)) + return cursor.fetchone()[0] return result def retrieve_species_id(group): - result = fetch1("select SpeciesId from InbredSet where Name = '%s'" % ( - group), "/cross/" + group + ".json", lambda r: (r["species_id"],))[0] - return result + with database_connection() as conn, conn.cursor() as cursor: + cursor.execute("SELECT SpeciesId FROM InbredSet WHERE Name = %s", + (group,)) + return cursor.fetchone()[0] diff --git a/wqflask/maintenance/gen_ind_genofiles.py b/wqflask/maintenance/gen_ind_genofiles.py index 8b958efa..b755c648 100644 --- a/wqflask/maintenance/gen_ind_genofiles.py +++ b/wqflask/maintenance/gen_ind_genofiles.py @@ -58,7 +58,7 @@ def main(args): par_f1s = {} # List of files directly taken from command line arguments, with titles just set to the filename for group in args[4:]: - file_name = geno_dir + group + ".geno" if ".geno" not in group else group + file_name = geno_dir + group + ".geno" if ".geno" not in group else geno_dir + group source_files.append({'title': file_name[:-5], 'location': file_name}) if len(source_files) > 1: @@ -66,17 +66,19 @@ def main(args): target_json_loc = out_dir + ".".join(args[3].split(".")[:-1]) + ".json" target_json = {'genofile': []} - # Generate the output .geno files - for source_file in source_files: - filename, samples = generate_new_genofile(source_file['location'], target_file, par_f1s, out_dir) + # Generate the output .geno files + for source_file in source_files: + filename, samples = generate_new_genofile(source_file['location'], target_file, par_f1s, out_dir) - target_json['genofile'].append({ - 'location': filename.split("/")[-1], - 'title': source_file['title'], - 'sample_list': samples - }) + target_json['genofile'].append({ + 'location': filename.split("/")[-1], + 'title': source_file['title'], + 'sample_list': samples + }) - json.dump(target_json, open(target_json_loc, "w")) + json.dump(target_json, open(target_json_loc, "w")) + else: + filename, samples = generate_new_genofile(source_files[0]['location'], target_file, par_f1s, out_dir) def get_strain_for_sample(sample): query = ( @@ -88,7 +90,8 @@ def get_strain_for_sample(sample): with conn().cursor() as cursor: cursor.execute(query, {"name": sample.strip()}) - return cursor.fetchone()[0] + strain = cursor.fetchone()[0] + return strain def generate_new_genofile(source_genofile, target_genofile, par_f1s, out_dir): source_samples = group_samples(source_genofile) @@ -110,7 +113,7 @@ def generate_new_genofile(source_genofile, target_genofile, par_f1s, out_dir): fh.write("@" + metadata + ":" + source_genotypes[metadata] + "\n") header_line = ["Chr", "Locus", "cM", "Mb"] + target_samples - fh.write("\t".join(header_line)) + fh.write("\t".join(header_line) + "\n") for marker in source_genotypes['markers']: line_items = [ @@ -172,7 +175,8 @@ def group_samples(target_file: str) -> List: if line[0] in ["#", "@"] or not len(line): continue - line_items = line.split("\t") + line_items = line.split() + sample_list = [item for item in line_items if item not in ["Chr", "Locus", "Mb", "cM"]] break diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index 22d73ba3..0d9372ff 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -33,8 +33,6 @@ Redis = get_redis_conn() import urllib.parse from wqflask.database import database_connection -from utility.logger import getLogger -logger = getLogger(__name__) def parse_db_uri(): diff --git a/wqflask/tests/unit/wqflask/api/test_mapping.py b/wqflask/tests/unit/wqflask/api/test_mapping.py index 159c982b..006e9826 100644 --- a/wqflask/tests/unit/wqflask/api/test_mapping.py +++ b/wqflask/tests/unit/wqflask/api/test_mapping.py @@ -25,7 +25,9 @@ class TestMapping(unittest.TestCase): "maf": 0.01, "use_loco": True, "num_perm": 0, - "perm_check": False + "perm_check": False, + "transform": False, + "genofile": False } results = initialize_parameters( @@ -40,8 +42,9 @@ class TestMapping(unittest.TestCase): "pair_scan": "true", "interval_mapping": "true", "use_loco": "true", - "num_perm": "14" - + "num_perm": "14", + "transform": "qnorm", + "genofile": "BXD.8.geno" } results_2 = initialize_parameters( @@ -53,7 +56,9 @@ class TestMapping(unittest.TestCase): "maf": 0.01, "use_loco": True, "num_perm": 14, - "perm_check": "ON" + "perm_check": "ON", + "transform": "qnorm", + "genofile": "BXD.8.geno" } self.assertEqual(results_2, expected_results) diff --git a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py index 611c0d70..53d96d7f 100644 --- a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py +++ b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py @@ -165,12 +165,12 @@ X\tM5\t12\tQ\tE\tMMB\tR\t21.1\tW\t0.65\t0.6""" this_dataset={}, gwa_output_filename=".xw/") expected_results = [ {'name': 'M1', 'chr': 'X/Y', 'Mb': 2.8457155e-05, 'p_value': 0.85, - 'additive': -23.3, 'lod_score': 0.07058107428570727}, + 'additive': -11.65, 'lod_score': 0.07058107428570727}, {'name': 'M2', 'chr': 4, 'Mb': 1.2e-05, 'p_value': 0.5, - 'additive': -24.0, 'lod_score': 0.3010299956639812}, + 'additive': -12.0, 'lod_score': 0.3010299956639812}, {'name': 'M4', 'chr': 'Y', 'Mb': 1.2e-05, 'p_value': 0.7, - 'additive': -11.6, 'lod_score': 0.1549019599857432}, - {'name': 'M5', 'chr': 'X', 'Mb': 1.2e-05, 'p_value': 0.6, 'additive': -21.1, 'lod_score': 0.22184874961635637}] + 'additive': -5.8, 'lod_score': 0.1549019599857432}, + {'name': 'M5', 'chr': 'X', 'Mb': 1.2e-05, 'p_value': 0.6, 'additive': -10.55, 'lod_score': 0.22184874961635637}] self.assertEqual(expected_results, results) @mock.patch("wqflask.marker_regression.gemma_mapping.TEMPDIR", "/home/tmp") diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index d4256a46..df7156b4 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -33,8 +33,7 @@ from math import * import utility.corestats as corestats from base import webqtlConfig from utility.pillow_utils import draw_rotated_text -import utility.logger -logger = utility.logger.getLogger(__name__) + # ---- Define common colours ---- # BLUE = ImageColor.getrgb("blue") @@ -105,7 +104,6 @@ def find_outliers(vals): """ if vals: - #logger.debug("vals is:", pf(vals)) stats = corestats.Stats(vals) low_hinge = stats.percentile(25) up_hinge = stats.percentile(75) diff --git a/wqflask/utility/benchmark.py b/wqflask/utility/benchmark.py deleted file mode 100644 index 6ece2f21..00000000 --- a/wqflask/utility/benchmark.py +++ /dev/null @@ -1,52 +0,0 @@ -import collections -import inspect -import time -from utility.tools import LOG_BENCH - -from utility.logger import getLogger -logger = getLogger(__name__) - - -class Bench: - entries = collections.OrderedDict() - - def __init__(self, name=None, write_output=LOG_BENCH): - self.name = name - self.write_output = write_output - - def __enter__(self): - if self.write_output: - if self.name: - logger.debug("Starting benchmark: %s" % (self.name)) - else: - logger.debug("Starting benchmark at: %s [%i]" % ( - inspect.stack()[1][3], inspect.stack()[1][2])) - self.start_time = time.time() - - def __exit__(self, type, value, traceback): - time_taken = time.time() - self.start_time - if self.write_output: - if self.name: - name = self.name - else: - name = "That" - - logger.info(" %s took: %f seconds" % (name, (time_taken))) - - if self.name: - Bench.entries[self.name] = Bench.entries.get( - self.name, 0) + time_taken - - @classmethod - def report(cls): - total_time = sum( - (time_taken for time_taken in list(cls.entries.values()))) - print("\nTiming report\n") - for name, time_taken in list(cls.entries.items()): - percent = int(round((time_taken / total_time) * 100)) - print("[{}%] {}: {}".format(percent, name, time_taken)) - print() - - def reset(cls): - """Reset the entries""" - cls.entries = collections.OrderedDict() diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py index e619b7b6..c7a1ea59 100644 --- a/wqflask/utility/gen_geno_ob.py +++ b/wqflask/utility/gen_geno_ob.py @@ -1,7 +1,3 @@ -import utility.logger -logger = utility.logger.getLogger(__name__) - - class genotype: """ Replacement for reaper.Dataset so we can remove qtlreaper use while still generating mapping output figure diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py index 27dd0729..4229a91f 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -6,9 +6,6 @@ from utility import hmac from flask import g -import logging -logger = logging.getLogger(__name__) - def get_species_dataset_trait(self, start_vars): if "temp_trait" in list(start_vars.keys()): diff --git a/wqflask/utility/logger.py b/wqflask/utility/logger.py index d706e32a..65f2f1ee 100644 --- a/wqflask/utility/logger.py +++ b/wqflask/utility/logger.py @@ -27,7 +27,6 @@ # We'll add more overrides soon. import logging -import string from inspect import isfunction from pprint import pformat as pf from inspect import stack diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py index 5713e155..e302df18 100644 --- a/wqflask/utility/pillow_utils.py +++ b/wqflask/utility/pillow_utils.py @@ -2,9 +2,6 @@ from PIL import Image, ImageColor, ImageDraw, ImageFont from utility.tools import TEMPDIR -import utility.logger -logger = utility.logger.getLogger(__name__) - BLACK = ImageColor.getrgb("black") WHITE = ImageColor.getrgb("white") diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 641d973e..945efbbd 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -5,8 +5,6 @@ import datetime import redis # used for collections from utility.hmac import hmac_creation -from utility.logger import getLogger -logger = getLogger(__name__) def get_redis_conn(): diff --git a/wqflask/wqflask/api/gen_menu.py b/wqflask/wqflask/api/gen_menu.py index 5d239343..45d5739e 100644 --- a/wqflask/wqflask/api/gen_menu.py +++ b/wqflask/wqflask/api/gen_menu.py @@ -1,8 +1,5 @@ from gn3.db.species import get_all_species -import utility.logger -logger = utility.logger.getLogger(__name__) - def gen_dropdown_json(conn): """Generates and outputs (as json file) the data for the main dropdown menus on the home page @@ -31,7 +28,6 @@ def get_groups(species, conn): "InbredSet.FullName) ASC, IFNULL(InbredSet.Family, " "InbredSet.FullName) ASC, InbredSet.FullName ASC, " "InbredSet.MenuOrderId ASC").format(species_name) - # logger.debug(query) cursor.execute(query) results = cursor.fetchall() for result in results: diff --git a/wqflask/wqflask/api/mapping.py b/wqflask/wqflask/api/mapping.py index 25643b4e..5eacc83a 100644 --- a/wqflask/wqflask/api/mapping.py +++ b/wqflask/wqflask/api/mapping.py @@ -2,10 +2,11 @@ from base import data_set from base.trait import create_trait, retrieve_sample_data from wqflask.marker_regression import gemma_mapping, rqtl_mapping +from wqflask.show_trait.show_trait import normf def do_mapping_for_api(start_vars): - assert('db' in start_vars) - assert('trait_id' in start_vars) + if ('db' not in start_vars) or ("trait_id" not in start_vars): + raise ValueError("Mapping: db and trait_id are not in start_vars") dataset = data_set.create_dataset(dataset_name=start_vars['db']) dataset.group.get_markers() @@ -18,12 +19,13 @@ def do_mapping_for_api(start_vars): mapping_params = initialize_parameters(start_vars, dataset, this_trait) genofile_samplelist = [] - if mapping_params['genofile']: + if mapping_params.get('genofile'): dataset.group.genofile = mapping_params['genofile'] genofile_samplelist = get_genofile_samplelist(dataset) if (len(genofile_samplelist) > 0): - for sample in genofile_samplelist: + samplelist = genofile_samplelist + for sample in samplelist: in_trait_data = False for item in this_trait.data: if this_trait.data[item].name == sample: @@ -35,7 +37,8 @@ def do_mapping_for_api(start_vars): if not in_trait_data: vals.append("x") else: - for sample in dataset.group.samplelist: + samplelist = dataset.group.samplelist + for sample in samplelist: in_trait_data = False for item in this_trait.data: if this_trait.data[item].name == sample: @@ -47,19 +50,33 @@ def do_mapping_for_api(start_vars): if not in_trait_data: vals.append("x") + if mapping_params.get('transform') == "qnorm": + vals_minus_x = [float(val) for val in vals if val != "x"] + qnorm_vals = normf(vals_minus_x) + qnorm_vals_with_x = [] + counter = 0 + for val in vals: + if val == "x": + qnorm_vals_with_x.append("x") + else: + qnorm_vals_with_x.append(qnorm_vals[counter]) + counter += 1 + + vals = qnorm_vals_with_x + # It seems to take an empty string as default. This should probably be changed. covariates = "" - if mapping_params['mapping_method'] == "gemma": + if mapping_params.get('mapping_method') == "gemma": header_row = ["name", "chr", "Mb", "lod_score", "p_value"] # gemma_mapping returns both results and the filename for LOCO, so need to only grab the former for api - if mapping_params['use_loco'] == "True": + if mapping_params.get('use_loco') == "True": result_markers = gemma_mapping.run_gemma( this_trait, dataset, samples, vals, covariates, mapping_params['use_loco'], mapping_params['maf'])[0] else: result_markers = gemma_mapping.run_gemma( this_trait, dataset, samples, vals, covariates, mapping_params['use_loco'], mapping_params['maf']) - elif mapping_params['mapping_method'] == "rqtl": + elif mapping_params.get('mapping_method') == "rqtl": header_row = ["name", "chr", "cM", "lod_score"] if mapping_params['num_perm'] > 0: _sperm_output, _suggestive, _significant, result_markers = rqtl_mapping.run_rqtl(this_trait.name, vals, samples, dataset, None, "Mb", mapping_params['rqtl_model'], @@ -72,10 +89,10 @@ def do_mapping_for_api(start_vars): mapping_params['do_control'], mapping_params['control_marker'], mapping_params['manhattan_plot'], None) - if mapping_params['limit_to']: + if mapping_params.get('limit_to'): result_markers = result_markers[:mapping_params['limit_to']] - if mapping_params['format'] == "csv": + if mapping_params.get('format') == "csv": output_rows = [] output_rows.append(header_row) for marker in result_markers: @@ -148,6 +165,10 @@ def initialize_parameters(start_vars, dataset, this_trait): except: mapping_params['perm_check'] = False + mapping_params['transform'] = False + if 'transform' in start_vars: + mapping_params['transform'] = start_vars['transform'] + mapping_params['genofile'] = False if 'genofile' in start_vars: mapping_params['genofile'] = start_vars['genofile'] diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index 3d33cc87..95cd2953 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -25,8 +25,6 @@ from utility.tools import flat_files from wqflask.database import database_connection -import utility.logger -logger = utility.logger.getLogger(__name__) version = "pre1" @@ -275,8 +273,6 @@ def get_dataset_info(dataset_name, group_name=None, file_format="json"): InbredSet.Name = "{0}" AND PublishXRef.Id = "{1}" """.format(group_name, dataset_name) - logger.debug("QUERY:", pheno_query) - pheno_results = g.db.execute(pheno_query) dataset = pheno_results.fetchone() diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 891da437..87a96a26 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -21,9 +21,7 @@ from base.trait import retrieve_trait_info from base.trait import jsonable from base.data_set import create_dataset -from utility.logger import getLogger -logger = getLogger(__name__) Redis = get_redis_conn() @@ -48,8 +46,6 @@ def report_change(len_before, len_now): if new_length: flash("We've added {} to your collection.".format( numify(new_length, 'new trait', 'new traits'))) - else: - logger.debug("No new traits were added.") @app.route("/collections/store_trait_list", methods=('POST',)) @@ -273,7 +269,10 @@ def view_collection(): trait_ob, dataset, get_qtl_info=True) trait_obs.append(trait_ob) - json_version.append(jsonable(trait_ob)) + trait_json = jsonable(trait_ob) + trait_json['trait_info_str'] = trait_info_str(trait_ob) + + json_version.append(trait_json) collection_info = dict( trait_obs=trait_obs, @@ -285,6 +284,7 @@ def view_collection(): else: return render_template( "collections/view.html", + traits_json=json_version, trait_info_str=trait_info_str, **collection_info) diff --git a/wqflask/wqflask/correlation/corr_scatter_plot.py b/wqflask/wqflask/correlation/corr_scatter_plot.py index cafb9265..5df28c45 100644 --- a/wqflask/wqflask/correlation/corr_scatter_plot.py +++ b/wqflask/wqflask/correlation/corr_scatter_plot.py @@ -8,9 +8,6 @@ from utility import corr_result_helpers from scipy import stats import numpy as np -import utility.logger -logger = utility.logger.getLogger(__name__) - class CorrScatterPlot: """Page that displays a correlation scatterplot with a line fitted to it""" diff --git a/wqflask/wqflask/correlation/rust_correlation.py b/wqflask/wqflask/correlation/rust_correlation.py index f06ee95c..251ada7b 100644 --- a/wqflask/wqflask/correlation/rust_correlation.py +++ b/wqflask/wqflask/correlation/rust_correlation.py @@ -25,15 +25,19 @@ def query_probes_metadata(dataset, trait_list): query = """ SELECT ProbeSet.Name,ProbeSet.Chr,ProbeSet.Mb, - Symbol,mean,description,additive,LRS,Geno.Chr, Geno.Mb - from Geno, Species,ProbeSet,ProbeSetXRef,ProbeSetFreeze - where ProbeSet.Name in ({}) and - Species.Name = %s and - Geno.Name = ProbeSetXRef.Locus and - Geno.SpeciesId = Species.Id and - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - ProbeSetFreeze.Name = %s + ProbeSet.Symbol,ProbeSetXRef.mean,ProbeSet.description, + ProbeSetXRef.additive,ProbeSetXRef.LRS,Geno.Chr, Geno.Mb + FROM ProbeSet INNER JOIN ProbeSetXRef + ON ProbeSet.Id=ProbeSetXRef.ProbeSetId + INNER JOIN Geno + ON ProbeSetXRef.Locus = Geno.Name + INNER JOIN Species + ON Geno.SpeciesId = Species.Id + WHERE ProbeSet.Name in ({}) AND + Species.Name = %s AND + ProbeSetXRef.ProbeSetFreezeId IN ( + SELECT ProbeSetFreeze.Id + FROM ProbeSetFreeze WHERE ProbeSetFreeze.Name = %s) """.format(", ".join(["%s"] * len(trait_list))) cursor.execute(query, @@ -45,6 +49,11 @@ def query_probes_metadata(dataset, trait_list): def get_metadata(dataset, traits): + """Retrieve the metadata""" + def __location__(probe_chr, probe_mb): + if probe_mb: + return f"Chr{probe_chr}: {probe_mb:.6f}" + return f"Chr{probe_chr}: ???" return {trait_name: { "name": trait_name, @@ -56,7 +65,7 @@ def get_metadata(dataset, traits): "description": description, "additive": additive, "lrs_score": f"{lrs:3.1f}", - "location": f"Chr{probe_chr}: {probe_mb:.6f}", + "location": __location__(probe_chr, probe_mb), "lrs_location": f"Chr{chr_score}: {mb:.6f}" } for trait_name, probe_chr, probe_mb, symbol, mean, description, diff --git a/wqflask/wqflask/ctl/ctl_analysis.py b/wqflask/wqflask/ctl/ctl_analysis.py index bb928ec5..96a47eb8 100644 --- a/wqflask/wqflask/ctl/ctl_analysis.py +++ b/wqflask/wqflask/ctl/ctl_analysis.py @@ -24,8 +24,6 @@ from utility.tools import locate, GN2_BRANCH_URL from rpy2.robjects.packages import importr -import utility.logger -logger = utility.logger.getLogger(__name__) # Get pointers to some common R functions r_library = ro.r["library"] # Map the library function @@ -42,14 +40,9 @@ r_as_numeric = ro.r["as.numeric"] # Map the write.table function class CTL: def __init__(self): - logger.info("Initialization of CTL") - #log = r_file("/tmp/genenetwork_ctl.log", open = "wt") - # r_sink(log) # Uncomment the r_sink() commands to log output from stdout/stderr to a file - #r_sink(log, type = "message") # Load CTL - Should only be done once, since it is quite expensive r_library("ctl") r_options(stringsAsFactors=False) - logger.info("Initialization of CTL done, package loaded in R session") # Map the CTLscan function self.r_CTLscan = ro.r["CTLscan"] # Map the CTLsignificant function @@ -60,7 +53,6 @@ class CTL: self.r_plotCTLobject = ro.r["plot.CTLobject"] self.nodes_list = [] self.edges_list = [] - logger.info("Obtained pointers to CTL functions") self.gn2_url = GN2_BRANCH_URL @@ -85,21 +77,12 @@ class CTL: self.edges_list.append(edge_dict) def run_analysis(self, requestform): - logger.info("Starting CTL analysis on dataset") self.trait_db_list = [trait.strip() for trait in requestform['trait_list'].split(',')] self.trait_db_list = [x for x in self.trait_db_list if x] - - logger.debug("strategy:", requestform.get("strategy")) strategy = requestform.get("strategy") - - logger.debug("nperm:", requestform.get("nperm")) nperm = int(requestform.get("nperm")) - - logger.debug("parametric:", requestform.get("parametric")) parametric = bool(requestform.get("parametric")) - - logger.debug("significance:", requestform.get("significance")) significance = float(requestform.get("significance")) # Get the name of the .geno file belonging to the first phenotype @@ -109,7 +92,6 @@ class CTL: genofilelocation = locate(dataset.group.name + ".geno", "genotype") parser = genofile_parser.ConvertGenoFile(genofilelocation) parser.process_csv() - logger.debug("dataset group: ", dataset.group) # Create a genotype matrix individuals = parser.individuals markers = [] @@ -119,8 +101,6 @@ class CTL: markers.append(marker["genotypes"]) genotypes = list(itertools.chain(*markers)) - logger.debug(len(genotypes) / len(individuals), - "==", len(parser.markers)) rGeno = r_t(ro.r.matrix(r_unlist(genotypes), nrow=len(markernames), ncol=len( individuals), dimnames=r_list(markernames, individuals), byrow=True)) @@ -128,7 +108,6 @@ class CTL: # Create a phenotype matrix traits = [] for trait in self.trait_db_list: - logger.debug("retrieving data for", trait) if trait != "": ts = trait.split(':') gt = create_trait(name=ts[0], dataset_name=ts[1]) @@ -142,8 +121,6 @@ class CTL: rPheno = r_t(ro.r.matrix(r_as_numeric(r_unlist(traits)), nrow=len(self.trait_db_list), ncol=len( individuals), dimnames=r_list(self.trait_db_list, individuals), byrow=True)) - logger.debug(rPheno) - # Use a data frame to store the objects rPheno = r_data_frame(rPheno, check_names=False) rGeno = r_data_frame(rGeno, check_names=False) @@ -195,8 +172,6 @@ class CTL: # Create the interactive graph for cytoscape visualization (Nodes and Edges) if not isinstance(significant, ri.RNULLType): for x in range(len(significant[0])): - logger.debug(significant[0][x], significant[1] - [x], significant[2][x]) # Debug to console # Source tsS = significant[0][x].split(':') # Target @@ -231,7 +206,6 @@ class CTL: n = n + 1 def process_results(self, results): - logger.info("Processing CTL output") template_vars = {} template_vars["results"] = self.results template_vars["elements"] = self.elements diff --git a/wqflask/wqflask/database.py b/wqflask/wqflask/database.py index 4b05c926..ec616d07 100644 --- a/wqflask/wqflask/database.py +++ b/wqflask/wqflask/database.py @@ -1,7 +1,6 @@ # Module to initialize sqlalchemy with flask import os import sys -from string import Template from typing import Tuple from urllib.parse import urlparse import importlib @@ -10,6 +9,14 @@ import contextlib import MySQLdb +def read_from_pyfile(pyfile, setting): + orig_sys_path = sys.path[:] + sys.path.insert(0, os.path.dirname(pyfile)) + module = importlib.import_module(os.path.basename(pyfile).strip(".py")) + sys.path = orig_sys_path[:] + return module.__dict__.get(setting) + + def sql_uri(): """Read the SQL_URI from the environment or settings file.""" return os.environ.get( @@ -39,7 +46,7 @@ def database_connection(): """ host, user, passwd, db_name, port = parse_db_url(sql_uri()) connection = MySQLdb.connect( - db=db_name, user=user, passwd=passwd, host=host, port=port, + db=db_name, user=user, passwd=passwd or '', host=host, port=port, autocommit=False # Required for roll-backs ) try: diff --git a/wqflask/wqflask/db_info.py b/wqflask/wqflask/db_info.py index 938c453e..f52c30e4 100644 --- a/wqflask/wqflask/db_info.py +++ b/wqflask/wqflask/db_info.py @@ -6,9 +6,6 @@ import re from flask import Flask, g -from utility.logger import getLogger -logger = getLogger(__name__) - class InfoPage: def __init__(self, start_vars): diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index b0756361..97143486 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -13,10 +13,6 @@ import sys from db import webqtlDatabaseFunction from utility.tools import GN2_BASE_URL -import logging -from utility.logger import getLogger -logger = getLogger(__name__) - class DoSearch: """Parent class containing parameters/functions used for all searches""" @@ -41,7 +37,6 @@ class DoSearch: def execute(self, query): """Executes query and returns results""" query = self.normalize_spaces(query) - logger.sql(query) results = g.db.execute(query, no_parameters=True).fetchall() return results @@ -55,7 +50,6 @@ class DoSearch: def mescape(self, *items): """Multiple escape""" escaped = [escape(str(item)) for item in items] - logger.debug("escaped is:", escaped) return tuple(escaped) def normalize_spaces(self, stringy): @@ -69,8 +63,6 @@ class DoSearch: if 'key' in search_type and search_type['key'] != None: search_type_string += '_' + search_type['key'] - logger.debug("search_type_string is:", search_type_string) - if search_type_string in cls.search_types: return cls.search_types[search_type_string] else: @@ -177,8 +169,6 @@ class MrnaAssaySearch(DoSearch): def run_combined(self, from_clause='', where_clause=''): """Generates and runs a combined search of an mRNA expression dataset""" - - logger.debug("Running ProbeSetSearch") #query = self.base_query + from_clause + " WHERE " + where_clause from_clause = self.normalize_spaces(from_clause) @@ -197,11 +187,8 @@ class MrnaAssaySearch(DoSearch): def run(self): """Generates and runs a simple search of an mRNA expression dataset""" - - logger.debug("Running ProbeSetSearch") where_clause = self.get_where_clause() query = self.base_query + "WHERE " + where_clause + "ORDER BY ProbeSet.symbol ASC" - return self.execute(query) @@ -310,9 +297,6 @@ class PhenotypeSearch(DoSearch): def run_combined(self, from_clause, where_clause): """Generates and runs a combined search of an phenotype dataset""" - - logger.debug("Running PhenotypeSearch") - from_clause = self.normalize_spaces(from_clause) query = (self.base_query + @@ -370,7 +354,6 @@ class GenotypeSearch(DoSearch): where_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % self.mescape(self.dataset.type, field), self.search_term)) - logger.debug("hello ;where_clause is:", pf(where_clause)) where_clause = "(%s) " % ' OR '.join(where_clause) return where_clause @@ -559,7 +542,6 @@ class LrsSearch(DoSearch): self.species_id) else: # Deal with >, <, >=, and <= - logger.debug("self.search_term is:", self.search_term) lrs_val = self.search_term[0] if self.search_type == "LOD": lrs_val = lrs_val * 4.61 @@ -794,7 +776,6 @@ class MeanSearch(MrnaAssaySearch): def run(self): self.where_clause = self.get_where_clause() - logger.debug("where_clause is:", pf(self.where_clause)) self.query = self.compile_final_query(where_clause=self.where_clause) @@ -824,9 +805,6 @@ class RangeSearch(MrnaAssaySearch): FROM ProbeSetData WHERE ProbeSetData.Id = ProbeSetXRef.dataId) > %s """ % (escape(self.search_term[0])) - - logger.debug("where_clause is:", pf(where_clause)) - return where_clause def run(self): @@ -932,11 +910,7 @@ class PvalueSearch(MrnaAssaySearch): self.search_operator, self.search_term[0]) - logger.debug("where_clause is:", pf(self.where_clause)) - self.query = self.compile_final_query(where_clause=self.where_clause) - - logger.sql(self.query) return self.execute(self.query) diff --git a/wqflask/wqflask/docs.py b/wqflask/wqflask/docs.py index 0a1a597d..9d58162e 100644 --- a/wqflask/wqflask/docs.py +++ b/wqflask/wqflask/docs.py @@ -2,9 +2,6 @@ import codecs from flask import g -from utility.logger import getLogger -logger = getLogger(__name__) - class Docs: diff --git a/wqflask/wqflask/export_traits.py b/wqflask/wqflask/export_traits.py index 0c80e9a4..4b37c7f7 100644 --- a/wqflask/wqflask/export_traits.py +++ b/wqflask/wqflask/export_traits.py @@ -14,8 +14,6 @@ from gn3.computations.gemma import generate_hash_of_string from base.trait import create_trait, retrieve_trait_info -from utility.logger import getLogger -logger = getLogger(__name__) def export_traits(targs, export_type): if export_type == "collection": diff --git a/wqflask/wqflask/external_tools/send_to_bnw.py b/wqflask/wqflask/external_tools/send_to_bnw.py index c1b14ede..dfb59c63 100644 --- a/wqflask/wqflask/external_tools/send_to_bnw.py +++ b/wqflask/wqflask/external_tools/send_to_bnw.py @@ -21,9 +21,6 @@ from base.trait import GeneralTrait from utility import helper_functions, corr_result_helpers -import utility.logger -logger = utility.logger.getLogger(__name__) - class SendToBNW: def __init__(self, start_vars): diff --git a/wqflask/wqflask/external_tools/send_to_geneweaver.py b/wqflask/wqflask/external_tools/send_to_geneweaver.py index 9a4f7150..a8066b43 100644 --- a/wqflask/wqflask/external_tools/send_to_geneweaver.py +++ b/wqflask/wqflask/external_tools/send_to_geneweaver.py @@ -26,9 +26,6 @@ from base.trait import GeneralTrait, retrieve_trait_info from base.species import TheSpecies from utility import helper_functions, corr_result_helpers -import utility.logger -logger = utility.logger.getLogger(__name__) - class SendToGeneWeaver: def __init__(self, start_vars): diff --git a/wqflask/wqflask/external_tools/send_to_webgestalt.py b/wqflask/wqflask/external_tools/send_to_webgestalt.py index 6e74f4fe..4de684b0 100644 --- a/wqflask/wqflask/external_tools/send_to_webgestalt.py +++ b/wqflask/wqflask/external_tools/send_to_webgestalt.py @@ -26,9 +26,6 @@ from base.trait import GeneralTrait, retrieve_trait_info from base.species import TheSpecies from utility import helper_functions, corr_result_helpers -import utility.logger -logger = utility.logger.getLogger(__name__) - class SendToWebGestalt: def __init__(self, start_vars): diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py index 53a124d0..56877524 100644 --- a/wqflask/wqflask/gsearch.py +++ b/wqflask/wqflask/gsearch.py @@ -11,13 +11,9 @@ from base import webqtlConfig from utility import hmac -from utility.benchmark import Bench from utility.authentication_tools import check_resource_availability from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string -from utility.logger import getLogger -logger = getLogger(__name__) - class GSearch: @@ -64,75 +60,72 @@ class GSearch: ORDER BY species_name, inbredset_name, tissue_name, probesetfreeze_name, probeset_name LIMIT 6000 """ % (self.terms) - with Bench("Running query"): - logger.sql(sql) - re = g.db.execute(sql).fetchall() + re = g.db.execute(sql).fetchall() trait_list = [] dataset_to_permissions = {} - with Bench("Creating trait objects"): - for i, line in enumerate(re): - this_trait = {} - this_trait['index'] = i + 1 - this_trait['name'] = line[5] - this_trait['dataset'] = line[3] - this_trait['dataset_fullname'] = line[4] - this_trait['hmac'] = hmac.data_hmac( - '{}:{}'.format(line[5], line[3])) - this_trait['species'] = line[0] - this_trait['group'] = line[1] - this_trait['tissue'] = line[2] - this_trait['symbol'] = "N/A" - if line[6]: - this_trait['symbol'] = line[6] - this_trait['description'] = "N/A" - if line[7]: - this_trait['description'] = line[7].decode( - 'utf-8', 'replace') - this_trait['location_repr'] = "N/A" - if (line[8] != "NULL" and line[8] != "") and (line[9] != 0): - this_trait['location_repr'] = 'Chr%s: %.6f' % ( - line[8], float(line[9])) - - this_trait['LRS_score_repr'] = "N/A" - this_trait['additive'] = "N/A" - this_trait['mean'] = "N/A" - - if line[11] != "" and line[11] != None: - this_trait['LRS_score_repr'] = f"{line[11]:.3f}" - if line[14] != "" and line[14] != None: - this_trait['additive'] = f"{line[14]:.3f}" - if line[10] != "" and line[10] != None: - this_trait['mean'] = f"{line[10]:.3f}" - - locus_chr = line[16] - locus_mb = line[17] - - max_lrs_text = "N/A" - if locus_chr and locus_mb: - max_lrs_text = f"Chr{locus_chr}: {locus_mb}" - this_trait['max_lrs_text'] = max_lrs_text - - this_trait['additive'] = "N/A" - if line[14] != "" and line[14] != None: - this_trait['additive'] = '%.3f' % line[14] - this_trait['dataset_id'] = line[15] - - dataset_ob = SimpleNamespace( - id=this_trait["dataset_id"], type="ProbeSet", name=this_trait["dataset"], species=this_trait["species"]) - if dataset_ob.id not in dataset_to_permissions: - permissions = check_resource_availability(dataset_ob) - dataset_to_permissions[dataset_ob.id] = permissions - else: - pemissions = dataset_to_permissions[dataset_ob.id] - if type(permissions['data']) is list: - if "view" not in permissions['data']: - continue - else: - if permissions['data'] == 'no-access': - continue - - trait_list.append(this_trait) + for i, line in enumerate(re): + this_trait = {} + this_trait['index'] = i + 1 + this_trait['name'] = line[5] + this_trait['dataset'] = line[3] + this_trait['dataset_fullname'] = line[4] + this_trait['hmac'] = hmac.data_hmac( + '{}:{}'.format(line[5], line[3])) + this_trait['species'] = line[0] + this_trait['group'] = line[1] + this_trait['tissue'] = line[2] + this_trait['symbol'] = "N/A" + if line[6]: + this_trait['symbol'] = line[6] + this_trait['description'] = "N/A" + if line[7]: + this_trait['description'] = line[7].decode( + 'utf-8', 'replace') + this_trait['location_repr'] = "N/A" + if (line[8] != "NULL" and line[8] != "") and (line[9] != 0): + this_trait['location_repr'] = 'Chr%s: %.6f' % ( + line[8], float(line[9])) + + this_trait['LRS_score_repr'] = "N/A" + this_trait['additive'] = "N/A" + this_trait['mean'] = "N/A" + + if line[11] != "" and line[11] != None: + this_trait['LRS_score_repr'] = f"{line[11]:.3f}" + if line[14] != "" and line[14] != None: + this_trait['additive'] = f"{line[14]:.3f}" + if line[10] != "" and line[10] != None: + this_trait['mean'] = f"{line[10]:.3f}" + + locus_chr = line[16] + locus_mb = line[17] + + max_lrs_text = "N/A" + if locus_chr and locus_mb: + max_lrs_text = f"Chr{locus_chr}: {locus_mb}" + this_trait['max_lrs_text'] = max_lrs_text + + this_trait['additive'] = "N/A" + if line[14] != "" and line[14] != None: + this_trait['additive'] = '%.3f' % line[14] + this_trait['dataset_id'] = line[15] + + dataset_ob = SimpleNamespace( + id=this_trait["dataset_id"], type="ProbeSet", name=this_trait["dataset"], species=this_trait["species"]) + if dataset_ob.id not in dataset_to_permissions: + permissions = check_resource_availability(dataset_ob) + dataset_to_permissions[dataset_ob.id] = permissions + else: + pemissions = dataset_to_permissions[dataset_ob.id] + if type(permissions['data']) is list: + if "view" not in permissions['data']: + continue + else: + if permissions['data'] == 'no-access': + continue + + trait_list.append(this_trait) self.trait_count = len(trait_list) self.trait_list = trait_list @@ -210,79 +203,84 @@ class GSearch: ORDER BY Species.`Name`, InbredSet.`Name`, PublishXRef.`Id` LIMIT 6000 """.format(group_clause, search_term) - logger.sql(sql) re = g.db.execute(sql).fetchall() trait_list = [] - with Bench("Creating trait objects"): - for i, line in enumerate(re): - this_trait = {} - this_trait['index'] = i + 1 - this_trait['name'] = str(line[4]) - if len(str(line[12])) == 3: - this_trait['display_name'] = str( - line[12]) + "_" + this_trait['name'] - else: - this_trait['display_name'] = this_trait['name'] - this_trait['dataset'] = line[2] - this_trait['dataset_fullname'] = line[3] - this_trait['hmac'] = hmac.data_hmac( - '{}:{}'.format(line[4], line[2])) - this_trait['species'] = line[0] - this_trait['group'] = line[1] - if line[9] != None and line[6] != None: - this_trait['description'] = line[6].decode( - 'utf-8', 'replace') - elif line[5] != None: - this_trait['description'] = line[5].decode( - 'utf-8', 'replace') - else: - this_trait['description'] = "N/A" - this_trait['dataset_id'] = line[14] - - this_trait['LRS_score_repr'] = "N/A" - this_trait['additive'] = "N/A" - this_trait['mean'] = "N/A" - - if line[10] != "" and line[10] != None: - this_trait['LRS_score_repr'] = f"{line[10]:.3f}" - # Some Max LRS values in the DB are wrongly listed as 0.000, but shouldn't be displayed - if this_trait['LRS_score_repr'] == "0.000": - this_trait['LRS_score_repr'] = "N/A" - if line[11] != "" and line[11] != None: - this_trait['additive'] = f"{line[11]:.3f}" - if line[13] != "" and line[13] != None: - this_trait['mean'] = f"{line[13]:.3f}" - - locus_chr = line[15] - locus_mb = line[16] - - max_lrs_text = "N/A" - if locus_chr and locus_mb: - max_lrs_text = f"Chr{locus_chr}: {locus_mb}" - this_trait['max_lrs_text'] = max_lrs_text - - this_trait['authors'] = line[7] - this_trait['year'] = line[8] - this_trait['pubmed_text'] = "N/A" - this_trait['pubmed_link'] = "N/A" - if this_trait['year'].isdigit(): - this_trait['pubmed_text'] = this_trait['year'] - if line[9] != "" and line[9] != None: - this_trait['pubmed_link'] = webqtlConfig.PUBMEDLINK_URL % line[8] - if line[12]: - this_trait['display_name'] = line[12] + \ - "_" + str(this_trait['name']) - - dataset_ob = SimpleNamespace(id=this_trait["dataset_id"], type="Publish", species=this_trait["species"]) - permissions = check_resource_availability(dataset_ob, this_trait['name']) - if type(permissions['data']) is list: - if "view" not in permissions['data']: - continue - else: - if permissions['data'] == 'no-access': - continue - - trait_list.append(this_trait) + for i, line in enumerate(re): + trait_dict = {} + trait_dict['index'] = i + 1 + trait_dict['name'] = str(line[4]) + if len(str(line[12])) == 3: + trait_dict['display_name'] = str( + line[12]) + "_" + trait_dict['name'] + else: + trait_dict['display_name'] = trait_dict['name'] + trait_dict['dataset'] = line[2] + trait_dict['dataset_fullname'] = line[3] + trait_dict['hmac'] = hmac.data_hmac( + '{}:{}'.format(line[4], line[2])) + trait_dict['species'] = line[0] + trait_dict['group'] = line[1] + if line[9] != None and line[6] != None: + trait_dict['description'] = line[6].decode( + 'utf-8', 'replace') + elif line[5] != None: + trait_dict['description'] = line[5].decode( + 'utf-8', 'replace') + else: + trait_dict['description'] = "N/A" + trait_dict['dataset_id'] = line[14] + + trait_dict['LRS_score_repr'] = "N/A" + trait_dict['additive'] = "N/A" + trait_dict['mean'] = "N/A" + + if line[10] != "" and line[10] != None: + trait_dict['LRS_score_repr'] = f"{line[10]:.3f}" + # Some Max LRS values in the DB are wrongly listed as 0.000, but shouldn't be displayed + if trait_dict['LRS_score_repr'] == "0.000": + trait_dict['LRS_score_repr'] = "N/A" + if line[11] != "" and line[11] != None: + trait_dict['additive'] = f"{line[11]:.3f}" + if line[13] != "" and line[13] != None: + trait_dict['mean'] = f"{line[13]:.3f}" + + locus_chr = line[15] + locus_mb = line[16] + + max_lrs_text = "N/A" + if locus_chr and locus_mb: + max_lrs_text = f"Chr{locus_chr}: {locus_mb}" + trait_dict['max_lrs_text'] = max_lrs_text + + trait_dict['authors'] = line[7] + + trait_dict['authors'] = line[7] + trait_dict['authors_display'] = trait_dict['authors'] + author_list = trait_dict['authors'].split(",") + if len(author_list) >= 2: + trait_dict['authors_display'] = (",").join(author_list[:2]) + ", et al." + + trait_dict['year'] = line[8] + trait_dict['pubmed_text'] = "N/A" + trait_dict['pubmed_link'] = "N/A" + if trait_dict['year'].isdigit(): + trait_dict['pubmed_text'] = trait_dict['year'] + if line[9] != "" and line[9] != None: + trait_dict['pubmed_link'] = webqtlConfig.PUBMEDLINK_URL % line[8] + if line[12]: + trait_dict['display_name'] = line[12] + \ + "_" + str(trait_dict['name']) + + dataset_ob = SimpleNamespace(id=trait_dict["dataset_id"], type="Publish", species=trait_dict["species"]) + permissions = check_resource_availability(dataset_ob, trait_dict['name']) + if type(permissions['data']) is list: + if "view" not in permissions['data']: + continue + else: + if permissions['data'] == 'no-access': + continue + + trait_list.append(trait_dict) self.trait_count = len(trait_list) self.trait_list = trait_list diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py index 001bab3b..1c8a4ff6 100644 --- a/wqflask/wqflask/heatmap/heatmap.py +++ b/wqflask/wqflask/heatmap/heatmap.py @@ -8,12 +8,9 @@ from utility import helper_functions from utility.tools import flat_files, REAPER_COMMAND, TEMPDIR from redis import Redis from flask import Flask, g -from utility.logger import getLogger Redis = Redis() -logger = getLogger(__name__) - class Heatmap: diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 6a62b45c..ef0c357e 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -42,17 +42,15 @@ from base import webqtlConfig from base.GeneralObject import GeneralObject from utility import webqtlUtil from utility import Plot -from utility.benchmark import Bench from wqflask.interval_analyst import GeneUtil from base.webqtlConfig import GENERATED_IMAGE_DIR from utility.pillow_utils import draw_rotated_text, draw_open_polygon -import utility.logger + try: # Only import this for Python3 from functools import reduce except: pass -logger = utility.logger.getLogger(__name__) RED = ImageColor.getrgb("red") BLUE = ImageColor.getrgb("blue") @@ -247,8 +245,6 @@ class DisplayMappingResults: HELP_PAGE_REF = '/glossary.html' def __init__(self, start_vars): - logger.info("Running qtlreaper") - self.temp_uuid = start_vars['temp_uuid'] self.dataset = start_vars['dataset'] @@ -590,9 +586,8 @@ class DisplayMappingResults: ################################################################ showLocusForm = "" intCanvas = Image.new("RGBA", size=(self.graphWidth, self.graphHeight)) - with Bench("Drawing Plot"): - gifmap = self.plotIntMapping( - intCanvas, startMb=self.startMb, endMb=self.endMb, showLocusForm=showLocusForm) + gifmap = self.plotIntMapping( + intCanvas, startMb=self.startMb, endMb=self.endMb, showLocusForm=showLocusForm) self.gifmap = gifmap.__str__() diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 6b525733..646728ba 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -13,8 +13,6 @@ 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__) GEMMAOPTS = "-debug" if WEBSERVER_MODE == 'PROD': diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index 2fa80841..75ee189e 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -5,9 +5,6 @@ from base.webqtlConfig import TMPDIR from utility import webqtlUtil from utility.tools import flat_files, PLINK_COMMAND -import utility.logger -logger = utility.logger.getLogger(__name__) - def run_plink(this_trait, dataset, species, vals, maf): plink_output_filename = webqtlUtil.genRandStr( @@ -15,13 +12,11 @@ def run_plink(this_trait, dataset, species, vals, maf): gen_pheno_txt_file(dataset, vals) plink_command = f"{PLINK_COMMAND} --noweb --bfile {flat_files('mapping')}/{dataset.group.name} --no-pheno --no-fid --no-parents --no-sex --maf {maf} --out { TMPDIR}{plink_output_filename} --assoc " - logger.debug("plink_command:", plink_command) os.system(plink_command) count, p_values = parse_plink_output(plink_output_filename, species) - logger.debug("p_values:", p_values) dataset.group.markers.add_pvalues(p_values) return dataset.group.markers.markers diff --git a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py index c4b495d7..4d5db2ee 100644 --- a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py +++ b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py @@ -10,9 +10,6 @@ from base.trait import GeneralTrait from base.data_set import create_dataset from utility.tools import flat_files, REAPER_COMMAND, TEMPDIR -import utility.logger -logger = utility.logger.getLogger(__name__) - def run_reaper(this_trait, this_dataset, samples, vals, json_data, num_perm, boot_check, num_bootstrap, do_control, control_marker, manhattan_plot, first_run=True, output_files=None): """Generates p-values for each marker using qtlreaper""" @@ -67,8 +64,6 @@ def run_reaper(this_trait, this_dataset, samples, vals, json_data, num_perm, boo opt_list), webqtlConfig.GENERATED_IMAGE_DIR, output_filename)) - - logger.debug("reaper_command:" + reaper_command) os.system(reaper_command) else: output_filename, permu_filename, bootstrap_filename = output_files diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py index 3bf06ea6..7d112c68 100644 --- a/wqflask/wqflask/marker_regression/rqtl_mapping.py +++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py @@ -17,9 +17,6 @@ from base.webqtlConfig import TMPDIR from base.trait import create_trait from utility.tools import locate, GN3_LOCAL_URL -import utility.logger -logger = utility.logger.getLogger(__name__) - def run_rqtl(trait_name, vals, samples, dataset, pair_scan, mapping_scale, model, method, num_perm, perm_strata_list, do_control, control_marker, manhattan_plot, cofactors): """Run R/qtl by making a request to the GN3 endpoint and reading in the output file(s)""" diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 35678df9..d9f33f8f 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -29,11 +29,7 @@ from base.trait import GeneralTrait from base import data_set from base import species from base import webqtlConfig -from utility import webqtlUtil -from utility import helper_functions -from utility import Plot, Bunch -from utility import temp_data -from utility.benchmark import Bench +from utility import webqtlUtil, helper_functions, hmac, Plot, Bunch, temp_data from wqflask.marker_regression import gemma_mapping, rqtl_mapping, qtlreaper_mapping, plink_mapping from wqflask.show_trait.SampleList import SampleList @@ -41,9 +37,6 @@ from utility.tools import locate, locate_ignore_error, GEMMA_COMMAND, PLINK_COMM from utility.external import shell from base.webqtlConfig import TMPDIR, GENERATED_TEXT_DIR -import utility.logger -logger = utility.logger.getLogger(__name__) - class RunMapping: @@ -207,13 +200,12 @@ class RunMapping: self.first_run = False self.score_type = "-logP" self.manhattan_plot = True - with Bench("Running GEMMA"): - if self.use_loco == "True": - marker_obs, self.output_files = gemma_mapping.run_gemma( - self.this_trait, self.dataset, self.samples, self.vals, self.covariates, self.use_loco, self.maf, self.first_run, self.output_files) - else: - marker_obs, self.output_files = gemma_mapping.run_gemma( - self.this_trait, self.dataset, self.samples, self.vals, self.covariates, self.use_loco, self.maf, self.first_run, self.output_files) + if self.use_loco == "True": + marker_obs, self.output_files = gemma_mapping.run_gemma( + self.this_trait, self.dataset, self.samples, self.vals, self.covariates, self.use_loco, self.maf, self.first_run, self.output_files) + else: + marker_obs, self.output_files = gemma_mapping.run_gemma( + self.this_trait, self.dataset, self.samples, self.vals, self.covariates, self.use_loco, self.maf, self.first_run, self.output_files) results = marker_obs elif self.mapping_method == "rqtl_plink": results = self.run_rqtl_plink() @@ -273,7 +265,6 @@ class RunMapping: self.control_marker = start_vars['control_marker'] self.do_control = start_vars['do_control'] - logger.info("Running qtlreaper") self.first_run = True self.output_files = None @@ -303,8 +294,6 @@ class RunMapping: results = plink_mapping.run_plink( self.this_trait, self.dataset, self.species, self.vals, self.maf) #results = self.run_plink() - else: - logger.debug("RUNNING NOTHING") self.no_results = False if len(results) == 0: @@ -319,6 +308,7 @@ class RunMapping: self.annotations_for_browser = [] highest_chr = 1 # This is needed in order to convert the highest chr to X/Y for marker in results: + marker['hmac'] = hmac.data_hmac('{}:{}'.format(marker['name'], self.dataset.group.name + "Geno")) if 'Mb' in marker: this_ps = marker['Mb'] * 1000000 else: @@ -378,33 +368,29 @@ class RunMapping: self.qtl_results.append(marker) total_markers = len(self.qtl_results) + export_mapping_results(self.dataset, self.this_trait, self.qtl_results, self.mapping_results_path, + self.mapping_method, self.mapping_scale, self.score_type, + self.transform, self.covariates, self.n_samples, self.vals_hash) + + if len(self.qtl_results) > 30000: + self.qtl_results = trim_markers_for_figure( + self.qtl_results) + self.results_for_browser = trim_markers_for_figure( + self.results_for_browser) + filtered_annotations = [] + for marker in self.results_for_browser: + for annot_marker in self.annotations_for_browser: + if annot_marker['rs'] == marker['rs']: + filtered_annotations.append(annot_marker) + break + self.annotations_for_browser = filtered_annotations + browser_files = write_input_for_browser( + self.dataset, self.results_for_browser, self.annotations_for_browser) + else: + browser_files = write_input_for_browser( + self.dataset, self.results_for_browser, self.annotations_for_browser) - with Bench("Exporting Results"): - export_mapping_results(self.dataset, self.this_trait, self.qtl_results, self.mapping_results_path, - self.mapping_method, 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: - self.qtl_results = trim_markers_for_figure( - self.qtl_results) - self.results_for_browser = trim_markers_for_figure( - self.results_for_browser) - filtered_annotations = [] - for marker in self.results_for_browser: - for annot_marker in self.annotations_for_browser: - if annot_marker['rs'] == marker['rs']: - filtered_annotations.append(annot_marker) - break - self.annotations_for_browser = filtered_annotations - browser_files = write_input_for_browser( - self.dataset, self.results_for_browser, self.annotations_for_browser) - else: - browser_files = write_input_for_browser( - self.dataset, self.results_for_browser, self.annotations_for_browser) - - with Bench("Trimming Markers for Table"): - self.trimmed_markers = trim_markers_for_table(results) + self.trimmed_markers = trim_markers_for_table(results) chr_lengths = get_chr_lengths( self.mapping_scale, self.mapping_method, self.dataset, self.qtl_results) diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 7a808ac9..ddf48d90 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -21,9 +21,6 @@ import re from pprint import pformat as pf -from utility.logger import getLogger -logger = getLogger(__name__) - def parse(pstring): """ @@ -45,7 +42,6 @@ def parse(pstring): for item in pstring: splat = re.split(separators, item) - logger.debug("splat is:", splat) # splat is an array of 1 if no match, otherwise more than 1 if len(splat) > 1: @@ -73,7 +69,6 @@ def parse(pstring): search_term=[item]) items.append(term) - logger.debug("* items are:", pf(items) + "\n") return(items) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 7134cc24..a835f631 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -25,8 +25,6 @@ from utility.authentication_tools import check_resource_availability from utility.tools import GN2_BASE_URL from utility.type_checking import is_str -from utility.logger import getLogger -logger = getLogger(__name__) class SearchResultPage: #maxReturn = 3000 @@ -56,7 +54,6 @@ class SearchResultPage: rx = re.compile( r'.*\W(href|http|sql|select|update)\W.*', re.IGNORECASE) if rx.match(search): - logger.debug("Regex failed search") self.search_term_exists = False return else: @@ -172,6 +169,10 @@ class SearchResultPage: trait_dict['pubmed_text'] = result[4] trait_dict['authors'] = result[3] + trait_dict['authors_display'] = trait_dict['authors'] + author_list = trait_dict['authors'].split(",") + if len(author_list) >= 2: + trait_dict['authors_display'] = (",").join(author_list[:2]) + ", et al." if result[6] != "" and result[6] != None: trait_dict['mean'] = f"{result[6]:.3f}" diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index d9821d9c..c1d9ad84 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -550,21 +550,21 @@ def get_max_digits(trait_vals): return max_digits -def quantile_normalize_vals(sample_groups, trait_vals): - def normf(trait_vals): - ranked_vals = ss.rankdata(trait_vals) - p_list = [] - for i, val in enumerate(trait_vals): - p_list.append(((i + 1) - 0.5) / len(trait_vals)) +def normf(trait_vals): + ranked_vals = ss.rankdata(trait_vals) + p_list = [] + for i, val in enumerate(trait_vals): + p_list.append(((i + 1) - 0.5) / len(trait_vals)) - z = ss.norm.ppf(p_list) + z = ss.norm.ppf(p_list) - normed_vals = [] - for rank in ranked_vals: - normed_vals.append("%0.3f" % z[int(rank) - 1]) + normed_vals = [] + for rank in ranked_vals: + normed_vals.append("%0.3f" % z[int(rank) - 1]) - return normed_vals + return normed_vals +def quantile_normalize_vals(sample_groups, trait_vals): qnorm_by_group = [] for i, sample_type in enumerate(sample_groups): qnorm_vals = normf(trait_vals[i]) diff --git a/wqflask/wqflask/static/new/javascript/create_datatable.js b/wqflask/wqflask/static/new/javascript/create_datatable.js new file mode 100644 index 00000000..7635cae0 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/create_datatable.js @@ -0,0 +1,115 @@ +create_table = function(tableId="trait_table", tableData = [], columnDefs = [], customSettings = {}) { + + loadDataTable(tableId=tableId, tableData=tableData, customSettings, firstRun=true) + + var widthChange = 0; // For storing the change in width so overall table width can be adjusted by that amount + function loadDataTable(tableId, tableData, customSettings, firstRun=false){ + if (!firstRun){ + columnDefs = setUserColumnsDefWidths(tableId, columnDefs); + } + + tableSettings = { + "drawCallback": function( settings ) { + $('#' + tableId + ' tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ + $(this).removeClass("selected") + } else if (event.target.tagName.toLowerCase() !== 'a') { + $(this).addClass("selected") + } + change_buttons() + }); + }, + "columns": columnDefs, + "sDom": "iti", + "destroy": true, + "autoWidth": false, + "bSortClasses": false, + "scrollY": "100vh", + "scrollCollapse": true, + "scroller": true, + "iDisplayLength": -1, + "initComplete": function (settings) { + // Add JQueryUI resizable functionality to each th in the ScrollHead table + $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ + handles: "e", + alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + resize: function( event, ui ) { + widthChange = ui.size.width - ui.originalSize.width; + }, + stop: function () { + saveColumnSettings(tableId, theTable); + loadDataTable(tableId, tableData, customSettings, firstRun=false); + } + }); + } + } + + if (tableData.length > 0){ + tableSettings["data"] = tableData + } + + // Replace default settings with custom settings or add custom settings if not already set in default settings + $.each(customSettings, function(key, value) { + tableSettings[key] = value + }); + + if (!firstRun){ + $('#' + tableId + '_container').css("width", String($('#' + tableId).width() + widthChange + 17) + "px"); // Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + + let checkedRows = getCheckedRows(tableId); + theTable = $('#' + tableId).DataTable(tableSettings); + if (checkedRows.length > 0){ + recheckRows(theTable, checkedRows); + } + } else { + theTable = $('#' + tableId).DataTable(tableSettings); + theTable.draw(); + $('#' + tableId + '_container').css("width", String($('#' + tableId).width() + 17) + "px"); + } + } + + theTable.on( 'order.dt search.dt draw.dt', function () { + theTable.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { + cell.innerHTML = i+1; + } ); + } ).draw(); + + window.addEventListener('resize', function(){ + theTable.columns.adjust(); + }); + + $('#' + tableId + '_searchbox').on( 'keyup', function () { + theTable.search($(this).val()).draw(); + } ); + + $('.toggle-vis').on('click', function (e) { + e.preventDefault(); + + function toggleColumn(column) { + // Toggle column visibility + column.visible( ! column.visible() ); + if (column.visible()){ + $(this).removeClass("active"); + } else { + $(this).addClass("active"); + } + } + + // Get the column API object + var targetCols = $(this).attr('data-column').split(",") + for (let i = 0; i < targetCols.length; i++){ + var column = theTable.column( targetCols[i] ); + toggleColumn(column); + } + } ); + + $('#redraw').on('click', function (e) { + e.preventDefault(); + trait_table.columns().visible( true ); + $('.toggle-vis.active').removeClass('active'); + }); +} 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 2e12ca26..cfc4f39e 100644 --- a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js +++ b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js @@ -1,23 +1,23 @@ -// ZS: This file initializes the tables for the show_trait page +// This file initializes the tables for the show_trait page -// ZS: This variable is just created to get the column position of the first case attribute (if case attributes exist), since it's needed to set the row classes in createdRow for the DataTable -var attribute_start_pos = 3; +// This variable is just created to get the column position of the first case attribute (if case attributes exist), since it's needed to set the row classes in createdRow for the DataTable +var attributeStartPos = 3; if (js_data.se_exists) { - attribute_start_pos += 2; + attributeStartPos += 2; } if (js_data.has_num_cases === true) { - attribute_start_pos += 1; + attributeStartPos += 1; } -build_columns = function() { - let column_list = [ +buildColumns = function() { + let columnList = [ { 'data': null, 'orderDataType': "dom-checkbox", 'searchable' : false, 'targets': 0, 'width': "25px", - 'render': function(data, type, row, meta) { + 'render': function() { return '<input type="checkbox" name="searchResult" class="checkbox edit_sample_checkbox" value="">' } }, @@ -35,7 +35,7 @@ build_columns = function() { 'data': null, 'targets': 2, 'width': "60px", - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<span class="edit_sample_sample_name">' + data.name + '</span>' } }, @@ -46,7 +46,7 @@ build_columns = function() { 'data': null, 'targets': 3, 'width': "60px", - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.value == null) { return '<input type="text" data-value="x" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_value" value="x" size=' + js_data.max_digits[0] + '>' } else { @@ -56,10 +56,10 @@ build_columns = function() { } ]; - attr_start = 4 + attrStart = 4 if (js_data.se_exists) { - attr_start += 2 - column_list.push( + attrStart += 2 + columnList.push( { 'bSortable': false, 'type': "natural", @@ -67,7 +67,7 @@ build_columns = function() { 'targets': 4, 'searchable' : false, 'width': "25px", - 'render': function(data, type, row, meta) { + 'render': function() { return '±' } }, @@ -78,7 +78,7 @@ build_columns = function() { 'data': null, 'targets': 5, 'width': "60px", - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.variance == null) { return '<input type="text" data-value="x" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" class="trait_value_input edit_sample_se" value="x" size=6>' } else { @@ -89,8 +89,8 @@ build_columns = function() { ); if (js_data.has_num_cases === true) { - attr_start += 1 - column_list.push( + attrStart += 1 + columnList.push( { 'title': "<div style='text-align: right;'>N</div>", 'orderDataType': "dom-input", @@ -98,7 +98,7 @@ build_columns = function() { 'data': null, 'targets': 6, 'width': "60px", - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.num_cases == null || data.num_cases == undefined) { return '<input type="text" data-value="x" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" class="trait_value_input edit_sample_num_cases" value="x" size=4 maxlength=4>' } else { @@ -111,8 +111,8 @@ build_columns = function() { } else { if (js_data.has_num_cases === true) { - attr_start += 1 - column_list.push( + attrStart += 1 + columnList.push( { 'title': "<div style='text-align: right;'>N</div>", 'orderDataType': "dom-input", @@ -120,7 +120,7 @@ build_columns = function() { 'data': null, 'targets': 4, 'width': "60px", - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.num_cases == null || data.num_cases == undefined) { return '<input type="text" data-value="x" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" class="trait_value_input edit_sample_num_cases" value="x" size=4 maxlength=4>' } else { @@ -132,14 +132,14 @@ build_columns = function() { } } - 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( + attrKeys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].id > js_data.attributes[b].id) ? 1 : -1) + for (i = 0; i < attrKeys.length; i++){ + columnList.push( { - '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>", + 'title': "<div title='" + js_data.attributes[attrKeys[i]].description + "' style='text-align: " + js_data.attributes[attrKeys[i]].alignment + "'>" + js_data.attributes[attrKeys[i]].name + "</div>", 'type': "natural", 'data': null, - 'targets': attr_start + i, + 'targets': attrStart + i, 'render': function(data, type, row, meta) { attr_name = Object.keys(data.extra_attributes).sort((a, b) => (parseInt(a) > parseInt(b)) ? 1 : -1)[meta.col - data.first_attr_col] @@ -156,30 +156,41 @@ build_columns = function() { } ) } - return column_list + return columnList } -columnDefs = build_columns() +columnDefs = buildColumns(); -loadDataTable(first_run=true, table_id="samples_primary", table_data=js_data['sample_lists'][0]) -if (js_data.sample_lists.length > 1){ - loadDataTable(first_run=true, table_id="samples_other", table_data=js_data['sample_lists'][1]) +tableIds = ["samples_primary"] +if (js_data.sample_lists.length > 1) { + tableIds.push("samples_other") } -function loadDataTable(first_run=false, table_id, table_data){ - if (!first_run){ - setUserColumnsDefWidths(table_id); - } +for (var i = 0; i < tableIds.length; i++) { + tableId = tableIds[i] - if (table_id == "samples_primary"){ - table_type = "Primary" + if (tableId == "samples_primary"){ + tableType = "Primary" } else { - table_type = "Other" + tableType = "Other" } - table_settings = { + tableSettings = { + "drawCallback": function( settings ) { + $('#' + tableId + ' tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ + $(this).removeClass("selected") + } else if (event.target.tagName.toLowerCase() !== 'a') { + $(this).addClass("selected") + } + }); + }, 'createdRow': function ( row, data, index ) { - $(row).attr('id', table_type + "_" + data.this_id) + $(row).attr('id', tableType + "_" + data.this_id) $(row).addClass("value_se"); if (data.outlier) { $(row).addClass("outlier"); @@ -202,85 +213,13 @@ function loadDataTable(first_run=false, table_id, table_data){ $('td', row).eq(4).addClass("column_name-num_cases") } } - - for (i=0; i < attr_keys.length; i++) { - $('td', row).eq(attribute_start_pos + i + 1).addClass("column_name-" + js_data.attributes[attr_keys[i]].name) - $('td', row).eq(attribute_start_pos + i + 1).attr("style", "text-align: " + js_data.attributes[attr_keys[i]].alignment + "; padding-top: 2px; padding-bottom: 0px;") + + for (j=0; j < attrKeys.length; j++) { + $('td', row).eq(attributeStartPos + j + 1).addClass("column_name-" + js_data.attributes[attrKeys[j]].name) + $('td', row).eq(attributeStartPos + j + 1).attr("style", "text-align: " + js_data.attributes[attrKeys[j]].alignment + "; padding-top: 2px; padding-bottom: 0px;") } - }, - 'data': table_data, - 'columns': columnDefs, - "order": [[1, "asc" ]], - "sDom": "iti", - "destroy": true, - "autoWidth": false, - "bSortClasses": false, - "scrollY": "100vh", - "scrollCollapse": true, - "scroller": true, - "iDisplayLength": -1, - "initComplete": function (settings) { - //Add JQueryUI resizable functionality to each th in the ScrollHead table - $('#' + table_id + '_wrapper .dataTables_scrollHead thead th').resizable({ - handles: "e", - alsoResize: '#' + table_id + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother - resize: function( event, ui ) { - width_change = ui.size.width - ui.originalSize.width; - }, - stop: function () { - saveColumnSettings(table_id, the_table); - loadDataTable(first_run=false, table_id, table_data); - } - }); } } - if (!first_run){ - $('#' + table_type.toLowerCase() + '_container').css("width", String($('#' + table_id).width() + width_change + 17) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly - - let checked_rows = get_checked_rows(table_id); - the_table = $('#' + table_id).DataTable(table_settings); - if (checked_rows.length > 0){ - recheck_rows(the_table, checked_rows); - } - } else { - the_table = $('#' + table_id).DataTable(table_settings); - the_table.draw(); - } - - the_table.on( 'order.dt search.dt draw.dt', function () { - the_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { - cell.innerHTML = i+1; - } ); - } ).draw(); - - if (first_run){ - $('#' + table_type.toLowerCase() + '_container').css("width", String($('#' + table_id).width() + 17) + "px"); - } - - $('#' + table_type.toLowerCase() + '_searchbox').on( 'keyup', function () { - $('#' + table_id).DataTable().search($(this).val()).draw(); - } ); - - $('.toggle-vis').on('click', function (e) { - e.preventDefault(); - - function toggle_column(column) { - //ZS: Toggle column visibility - column.visible( ! column.visible() ); - if (column.visible()){ - $(this).removeClass("active"); - } else { - $(this).addClass("active"); - } - } - - // Get the column API object - var target_cols = $(this).attr('data-column').split(",") - for (let i = 0; i < target_cols.length; i++){ - var column = the_table.column( target_cols[i] ); - toggle_column(column); - } - } ); - + create_table(tableId, js_data['sample_lists'][i], columnDefs, tableSettings); } diff --git a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js index e8b7ab83..59c23819 100644 --- a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js +++ b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js @@ -286,7 +286,6 @@ var data = [all_intercept_trace, primary_trace, other_trace] } - console.log("TRACE:", data) Plotly.newPlot('prob_plot_div', data, layout, root.modebar_options) }; diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 687cf85d..e9ea5afb 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -1,12 +1,12 @@ -var Stat_Table_Rows, is_number, +var statTableRows, isNumber, __hasProp = {}.hasOwnProperty, __slice = [].slice; -is_number = function(o) { +isNumber = function(o) { return !isNaN((o - 0) && o !== null); }; -Stat_Table_Rows = [ +statTableRows = [ { vn: "n_of_samples", pretty: "N of Samples", @@ -40,27 +40,27 @@ Stat_Table_Rows = [ if (js_data.dataset_type == "ProbeSet"){ if (js_data.data_scale == "linear_positive" || js_data.data_scale == "log2") { - Stat_Table_Rows.push({ + statTableRows.push({ vn: "range", pretty: "Range (log2)", digits: 3 }) } else { - Stat_Table_Rows.push({ + statTableRows.push({ vn: "range", pretty: "Range", digits: 3 }) } } else { - Stat_Table_Rows.push({ + statTableRows.push({ vn: "range", pretty: "Range", digits: 3 }) } -Stat_Table_Rows.push( +statTableRows.push( { vn: "range_fold", pretty: "Range (fold)", @@ -83,7 +83,7 @@ Stat_Table_Rows.push( } ); -var add, block_by_attribute_value, block_by_index, block_outliers, change_stats_value, create_value_dropdown, edit_data_change, export_sample_table_data, get_sample_table_data, hide_no_value, hide_tabs, make_table, on_corr_method_change, open_trait_selection, populate_sample_attributes_values_dropdown, process_id, update_bar_chart, update_histogram, update_prob_plot, reset_samples_table, sample_group_types, sample_lists, show_hide_outliers, stats_mdp_change, update_stat_values; +var add, blockByAttributeValue, blockByIndex, blockOutliers, changeStatsValue, createValueDropdown, editDataChange, exportSampleTableData, getSampleTableData, hideNoValue, hideTabs, makeTable, onCorrMethodChange, openTraitSelection, populateSampleAttributesValuesDropdown, processId, updateBarChart, updateHistogram, updateProbPlot, resetSamplesTable, sampleGroupTypes, sampleLists, showHideOutliers, statsMdpChange, updateStatValues; add = function() { var trait; trait = $("input[name=trait_hmac]").val(); @@ -92,11 +92,11 @@ add = function() { }); }; $('#add_to_collection').click(add); -sample_lists = js_data.sample_lists; -sample_group_types = js_data.sample_group_types; +sampleLists = js_data.sample_lists; +sampleGroupTypes = js_data.sample_group_types; $(".select_covariates").click(function () { - open_covariate_selection(); + openCovariateSelection(); }); $(".remove_covariates").click(function () { @@ -146,7 +146,7 @@ $(".remove_all_covariates").click(function() { $("input[name=covariates]").val(""); }) -open_trait_selection = function() { +openTraitSelection = function() { return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) { return function() { $.colorbox({ @@ -160,7 +160,7 @@ open_trait_selection = function() { }; })(this)); }; -open_covariate_selection = function() { +openCovariateSelection = function() { return $('#collections_holder').load('/collections/list #collections_list', (function(_this) { return function() { $.colorbox({ @@ -176,7 +176,7 @@ open_covariate_selection = function() { }; })(this)); }; -hide_tabs = function(start) { +hideTabs = function(start) { var x, _i, _results; _results = []; for (x = _i = start; start <= 10 ? _i <= 10 : _i >= 10; x = start <= 10 ? ++_i : --_i) { @@ -184,15 +184,15 @@ hide_tabs = function(start) { } return _results; }; -stats_mdp_change = function() { +statsMdpChange = function() { var selected; selected = $(this).val(); - hide_tabs(0); + hideTabs(0); return $("#stats_tabs" + selected).show(); }; -change_stats_value = function(sample_sets, category, value_type, decimal_places, effects) { +changeStatsValue = function(sample_sets, category, value_type, decimal_places, effects) { var current_value, id, in_box, the_value, title_value; - id = "#" + process_id(category, value_type); + id = "#" + processId(category, value_type); in_box = $(id).html; current_value = parseFloat($(in_box)).toFixed(decimal_places); the_value = sample_sets[category][value_type](); @@ -213,7 +213,7 @@ change_stats_value = function(sample_sets, category, value_type, decimal_places, return $(id).attr('title', title_value); } }; -update_stat_values = function(sample_sets) { +updateStatValues = function(sample_sets) { var category, row, show_effects, _i, _len, _ref, _results; show_effects = $(".tab-pane.active").attr("id") === "stats_tab"; _ref = ['samples_primary', 'samples_other', 'samples_all']; @@ -223,9 +223,9 @@ update_stat_values = function(sample_sets) { _results.push((function() { var _j, _len1, _results1; _results1 = []; - for (_j = 0, _len1 = Stat_Table_Rows.length; _j < _len1; _j++) { - row = Stat_Table_Rows[_j]; - _results1.push(change_stats_value(sample_sets, category, row.vn, row.digits, show_effects)); + for (_j = 0, _len1 = statTableRows.length; _j < _len1; _j++) { + row = statTableRows[_j]; + _results1.push(changeStatsValue(sample_sets, category, row.vn, row.digits, show_effects)); } return _results1; })()); @@ -233,7 +233,7 @@ update_stat_values = function(sample_sets) { return _results; }; -update_histogram_width = function() { +updateHistogram_width = function() { num_bins = $('#histogram').find('g.trace.bars').find('g.point').length if (num_bins < 10) { @@ -245,7 +245,7 @@ update_histogram_width = function() { } } -update_histogram = function() { +updateHistogram = function() { var x; var _i, _len, _ref, data; _ref = _.values(root.selected_samples[root.stats_group]); @@ -263,10 +263,10 @@ update_histogram = function() { } Plotly.newPlot('histogram', root.histogram_data, root.histogram_layout, root.modebar_options); - update_histogram_width() + updateHistogram_width() }; -update_bar_chart = function() { +updateBarChart = function() { var x; var _i, _len, _ref, data; _ref = _.values(root.selected_samples[root.stats_group]); @@ -302,7 +302,7 @@ update_bar_chart = function() { } } - new_chart_range = get_bar_range(trait_vals, trait_vars) + new_chart_range = getBarRange(trait_vals, trait_vars) root.bar_layout['yaxis']['range'] = new_chart_range @@ -327,7 +327,7 @@ update_bar_chart = function() { update_box_plot = function() { var y_value_list = [] - if (sample_lists.length > 1) { + if (sampleLists.length > 1) { i = 0; for (var sample_group in root.selected_samples){ var trait_sample_data = _.values(root.selected_samples[sample_group]) @@ -358,9 +358,9 @@ update_box_plot = function() { Plotly.newPlot('box_plot', root.box_data, root.box_layout, root.modebar_options) } -update_violin_plot = function() { +updateViolinPlot = function() { var y_value_list = [] - if (sample_lists.length > 1) { + if (sampleLists.length > 1) { i = 0; for (var sample_group in root.selected_samples){ var trait_sample_data = _.values(root.selected_samples[sample_group]) @@ -392,11 +392,11 @@ update_violin_plot = function() { } -update_prob_plot = function() { +updateProbPlot = function() { return root.redraw_prob_plot_impl(root.selected_samples, root.prob_plot_group); }; -make_table = function() { +makeTable = function() { var header, key, row, row_line, table, the_id, the_rows, value, _i, _len, _ref, _ref1; if (js_data.trait_symbol != null) { header = "<thead><tr><th style=\"color: white; background-color: #369; text-align: center;\" colspan=\"100%\">Trait " + js_data.trait_id + " - " + js_data.trait_symbol + "</th></tr><tr><th style=\"text-align: right; padding-left: 5px;\">Statistic</th>"; @@ -409,7 +409,7 @@ make_table = function() { for (key in _ref) { if (!__hasProp.call(_ref, key)) continue; value = _ref[key]; - the_id = process_id("column", key); + the_id = processId("column", key); if (Object.keys(_ref).length > 1) { header += "<th id=\"" + the_id + "\" style=\"text-align: right; padding-left: 5px;\">" + value + "</th>"; } else { @@ -419,8 +419,8 @@ make_table = function() { header += "</thead>"; the_rows = "<tbody>"; - for (_i = 0, _len = Stat_Table_Rows.length; _i < _len; _i++) { - row = Stat_Table_Rows[_i]; + for (_i = 0, _len = statTableRows.length; _i < _len; _i++) { + row = statTableRows[_i]; if ((row.vn == "range_fold") && js_data.dataset_type == "Publish"){ continue; } @@ -434,7 +434,7 @@ make_table = function() { for (key in _ref1) { if (!__hasProp.call(_ref1, key)) continue; value = _ref1[key]; - the_id = process_id(key, row.vn); + the_id = processId(key, row.vn); row_line += "<td id=\"" + the_id + "\" align=\"right\">N/A</td>"; } row_line += "</tr>"; @@ -444,7 +444,7 @@ make_table = function() { table = header + the_rows; return $("#stats_table").append(table); }; -process_id = function() { +processId = function() { var processed, value, values, _i, _len; values = 1 <= arguments.length ? __slice.call(arguments, 0) : []; @@ -461,14 +461,14 @@ process_id = function() { return processed; }; -fetch_sample_values = function() { +fetchSampleValues = function() { // This is meant to fetch all sample values using DataTables API, since they can't all be submitted with the form when using Scroller (and this should also be faster) sample_val_dict = {}; table = 'samples_primary'; if ($('#' + table).length){ - table_api = $('#' + table).DataTable(); - val_nodes = table_api.column(3).nodes().to$(); + tableApi = $('#' + table).DataTable(); + val_nodes = tableApi.column(3).nodes().to$(); for (_j = 0; _j < val_nodes.length; _j++){ sample_name = val_nodes[_j].childNodes[0].name.split(":")[1] sample_val = val_nodes[_j].childNodes[0].value @@ -479,7 +479,7 @@ fetch_sample_values = function() { return sample_val_dict; } -edit_data_change = function() { +editDataChange = function() { var already_seen, checkbox, name, real_dict, real_value, real_variance, row, rows, sample_sets, table, tables, _i, _j, _len, _len1; already_seen = {}; sample_sets = { @@ -497,20 +497,20 @@ edit_data_change = function() { for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; if ($('#' + table).length){ - table_api = $('#' + table).DataTable(); + tableApi = $('#' + table).DataTable(); sample_vals = []; - name_nodes = table_api.column(2).nodes().to$(); - val_nodes = table_api.column(3).nodes().to$(); - var_nodes = table_api.column(5).nodes().to$(); + name_nodes = tableApi.column(2).nodes().to$(); + val_nodes = tableApi.column(3).nodes().to$(); + var_nodes = tableApi.column(5).nodes().to$(); for (_j = 0; _j < val_nodes.length; _j++){ sample_val = val_nodes[_j].childNodes[0].value sample_name = $.trim(name_nodes[_j].childNodes[0].textContent) - if (is_number(sample_val) && sample_val !== "") { + if (isNumber(sample_val) && sample_val !== "") { sample_val = parseFloat(sample_val); sample_sets[table].add_value(sample_val); try { sample_var = var_nodes[_j].childNodes[0].value - if (is_number(sample_var)) { + if (isNumber(sample_var)) { sample_var = parseFloat(sample_var) } else { sample_var = null; @@ -534,37 +534,37 @@ edit_data_change = function() { } - update_stat_values(sample_sets); + updateStatValues(sample_sets); if ($('#histogram').hasClass('js-plotly-plot')){ - update_histogram(); + updateHistogram(); } if ($('#bar_chart').hasClass('js-plotly-plot')){ - update_bar_chart(); + updateBarChart(); } if ($('#box_plot').hasClass('js-plotly-plot')){ update_box_plot(); } if ($('#violin_plot').hasClass('js-plotly-plot')){ - update_violin_plot(); + updateViolinPlot(); } if ($('#prob_plot_div').hasClass('js-plotly-plot')){ - return update_prob_plot(); + return updateProbPlot(); } }; -show_hide_outliers = function() { +showHideOutliers = function() { var label; - label = $('#show_hide_outliers').val(); + label = $('#showHideOutliers').val(); if (label === "Hide Outliers") { - return $('#show_hide_outliers').val("Show Outliers"); + return $('#showHideOutliers').val("Show Outliers"); } else if (label === "Show Outliers") { - $('#show_hide_outliers').val("Hide Outliers"); + $('#showHideOutliers').val("Hide Outliers"); return console.log("Should be now Hide Outliers"); } }; -on_corr_method_change = function() { +onCorrMethodChange = function() { var corr_method; corr_method = $('select[name=corr_type]').val(); $('.correlation_desc').hide(); @@ -575,7 +575,7 @@ on_corr_method_change = function() { return $("#corr_sample_method").show(); } }; -$('select[name=corr_type]').change(on_corr_method_change); +$('select[name=corr_type]').change(onCorrMethodChange); on_dataset_change = function() { let dataset_type = $('select[name=corr_dataset] option:selected').data('type'); @@ -601,38 +601,38 @@ $('select[name=corr_dataset]').change(on_dataset_change); $('select[name=location_type]').change(on_dataset_change); submit_special = function(url) { - $("input[name=sample_vals]").val(JSON.stringify(fetch_sample_values())) + $("input[name=sample_vals]").val(JSON.stringify(fetchSampleValues())) $("#trait_data_form").attr("action", url); $("#trait_data_form").submit(); }; -get_table_contents_for_form_submit = function(form_id) { - // Borrowed code from - https://stackoverflow.com/questions/31418047/how-to-post-data-for-the-whole-table-using-jquery-datatables - let this_form = $("#" + form_id); - var params = primary_table.$('input').serializeArray(); - - $.each(params, function(){ - // If element doesn't exist in DOM - if(!$.contains(document, this_form[this.name])){ - // Create a hidden element - this_form.append( - $('<input>') - .attr('type', 'hidden') - .attr('name', this.name) - .val(this.value) - ); - } - }); -} - -var corr_input_list = ['sample_vals', 'corr_type', 'primary_samples', 'trait_id', 'dataset', 'group', 'tool_used', 'form_url', 'corr_sample_method', 'corr_samples_group', 'corr_dataset', 'min_expr', +// getTableContentsForFormSubmit = function(form_id) { +// // Borrowed code from - https://stackoverflow.com/questions/31418047/how-to-post-data-for-the-whole-table-using-jquery-datatables +// let this_form = $("#" + form_id); +// var params = primary_table.$('input').serializeArray(); + +// $.each(params, function(){ +// // If element doesn't exist in DOM +// if(!$.contains(document, this_form[this.name])){ +// // Create a hidden element +// this_form.append( +// $('<input>') +// .attr('type', 'hidden') +// .attr('name', this.name) +// .val(this.value) +// ); +// } +// }); +// } + +var corrInputList = ['sample_vals', 'corr_type', 'primary_samples', 'trait_id', 'dataset', 'group', 'tool_used', 'form_url', 'corr_sample_method', 'corr_samples_group', 'corr_dataset', 'min_expr', 'corr_return_results', 'location_type', 'loc_chr', 'min_loc_mb', 'max_loc_mb', 'p_range_lower', 'p_range_upper'] $(".test_corr_compute").on("click", (function(_this) { return function() { $('input[name=tool_used]').val("Correlation"); $('input[name=form_url]').val("/test_corr_compute"); - $('input[name=wanted_inputs]').val(corr_input_list.join(",")); + $('input[name=wanted_inputs]').val(corrInputList.join(",")); url = "/loading"; return submit_special(url); }; @@ -642,17 +642,17 @@ $(".corr_compute").on("click", (function(_this) { return function() { $('input[name=tool_used]').val("Correlation"); $('input[name=form_url]').val("/corr_compute"); - $('input[name=wanted_inputs]').val(corr_input_list.join(",")); + $('input[name=wanted_inputs]').val(corrInputList.join(",")); url = "/loading"; return submit_special(url); }; })(this)); -create_value_dropdown = function(value) { +createValueDropdown = function(value) { return "<option val=" + value + ">" + value + "</option>"; }; -populate_sample_attributes_values_dropdown = function() { +populateSampleAttributesValuesDropdown = function() { var attribute_info, key, sample_attributes, selected_attribute, value, _i, _len, _ref, _ref1, _results; $('#attribute_values').empty(); sample_attributes = []; @@ -682,33 +682,33 @@ populate_sample_attributes_values_dropdown = function() { for (_i = 0, _len = _ref1.length; _i < _len; _i++) { value = _ref1[_i]; if (value != ""){ - _results.push($(create_value_dropdown(value)).appendTo($('#attribute_values'))); + _results.push($(createValueDropdown(value)).appendTo($('#attribute_values'))); } } return _results; }; if (js_data.categorical_attr_exists == "true"){ - populate_sample_attributes_values_dropdown(); + populateSampleAttributesValuesDropdown(); } -$('#exclude_column').change(populate_sample_attributes_values_dropdown); -block_by_attribute_value = function() { +$('#exclude_column').change(populateSampleAttributesValuesDropdown); +blockByAttributeValue = function() { var attribute_name, cell_class, exclude_by_value; let exclude_group = $('#exclude_by_attr_group').val(); let exclude_column = $('#exclude_column').val(); if (exclude_group === "other") { - var table_api = $('#samples_other').DataTable(); + var tableApi = $('#samples_other').DataTable(); } else { - var table_api = $('#samples_primary').DataTable(); + var tableApi = $('#samples_primary').DataTable(); } exclude_by_value = $('#attribute_values').val(); - let val_nodes = table_api.column(3).nodes().to$(); - let exclude_val_nodes = table_api.column(attribute_start_pos + parseInt(exclude_column)).nodes().to$(); + let val_nodes = tableApi.column(3).nodes().to$(); + let exclude_val_nodes = tableApi.column(attributeStartPos + parseInt(exclude_column)).nodes().to$(); for (i = 0; i < exclude_val_nodes.length; i++) { if (exclude_val_nodes[i].hasChildNodes()) { @@ -721,11 +721,11 @@ block_by_attribute_value = function() { } } - edit_data_change(); + editDataChange(); }; -$('#exclude_by_attr').click(block_by_attribute_value); +$('#exclude_by_attr').click(blockByAttributeValue); -block_by_index = function() { +blockByIndex = function() { var end_index, error, index, index_list, index_set, index_string, start_index, _i, _j, _k, _len, _len1, _ref; index_string = $('#remove_samples_field').val(); index_list = []; @@ -751,11 +751,11 @@ block_by_index = function() { let block_group = $('#block_group').val(); if (block_group === "other") { - table_api = $('#samples_other').DataTable(); + tableApi = $('#samples_other').DataTable(); } else { - table_api = $('#samples_primary').DataTable(); + tableApi = $('#samples_primary').DataTable(); } - val_nodes = table_api.column(3).nodes().to$(); + val_nodes = tableApi.column(3).nodes().to$(); for (_k = 0, _len1 = index_list.length; _k < _len1; _k++) { index = index_list[_k]; val_nodes[index - 1].childNodes[0].value = "x"; @@ -771,14 +771,14 @@ filter_by_study = function() { if ($('#filter_study_group').length){ let block_group = $('#filter_study_group').val(); if (block_group === "other") { - table_api = $('#samples_other').DataTable(); + tableApi = $('#samples_other').DataTable(); } else { - table_api = $('#samples_primary').DataTable(); + tableApi = $('#samples_primary').DataTable(); } } - let sample_nodes = table_api.column(2).nodes().to$(); - let val_nodes = table_api.column(3).nodes().to$(); + let sample_nodes = tableApi.column(2).nodes().to$(); + let val_nodes = tableApi.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)){ @@ -794,20 +794,20 @@ filter_by_value = function() { let block_group = $('#filter_group').val(); if (block_group === "other") { - var table_api = $('#samples_other').DataTable(); + var tableApi = $('#samples_other').DataTable(); } else { - var table_api = $('#samples_primary').DataTable(); + var tableApi = $('#samples_primary').DataTable(); } - let val_nodes = table_api.column(3).nodes().to$(); + let val_nodes = tableApi.column(3).nodes().to$(); if (filter_column == "value"){ - var filter_val_nodes = table_api.column(3).nodes().to$(); + var filter_val_nodes = tableApi.column(3).nodes().to$(); } else if (filter_column == "stderr"){ - var filter_val_nodes = table_api.column(5).nodes().to$(); + var filter_val_nodes = tableApi.column(5).nodes().to$(); } else if (!isNaN(filter_column)){ - var filter_val_nodes = table_api.column(attribute_start_pos + parseInt(filter_column)).nodes().to$(); + var filter_val_nodes = tableApi.column(attributeStartPos + parseInt(filter_column)).nodes().to$(); } else { return false @@ -850,8 +850,8 @@ filter_by_value = function() { } }; -hide_no_value_filter = function( settings, data, dataIndex ) { - this_value = table_api.column(3).nodes().to$()[dataIndex].childNodes[0].value; +hideNoValue_filter = function( settings, data, dataIndex ) { + this_value = tableApi.column(3).nodes().to$()[dataIndex].childNodes[0].value; if (this_value == "x"){ return false } else { @@ -859,77 +859,77 @@ hide_no_value_filter = function( settings, data, dataIndex ) { } } -hide_no_value = function() { +hideNoValue = function() { tables = ['samples_primary', 'samples_other']; filter_active = $(this).data("active"); for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; if ($('#' + table).length) { - table_api = $('#' + table).DataTable(); + tableApi = $('#' + table).DataTable(); if (filter_active == "true"){ $(this).val("Hide No Value") - table_api.draw(); + tableApi.draw(); $(this).data("active", "false"); } else { $(this).val("Show No Value") - $.fn.dataTable.ext.search.push(hide_no_value_filter); - table_api.search(); - table_api.draw(); - $.fn.dataTable.ext.search.splice($.fn.dataTable.ext.search.indexOf(hide_no_value_filter, 1)); + $.fn.dataTable.ext.search.push(hideNoValue_filter); + tableApi.search(); + tableApi.draw(); + $.fn.dataTable.ext.search.splice($.fn.dataTable.ext.search.indexOf(hideNoValue_filter, 1)); $(this).data("active", "true"); } } } }; -$('#hide_no_value').click(hide_no_value); +$('#hideNoValue').click(hideNoValue); -block_outliers = function() { +blockOutliers = function() { return $('.outlier').each((function(_this) { return function(_index, element) { return $(element).find('.trait-value-input').val('x'); }; })(this)); }; -$('#block_outliers').click(block_outliers); +$('#blockOutliers').click(blockOutliers); -reset_samples_table = function() { +resetSamplesTable = function() { $('input[name="transform"]').val(""); $('span[name="transform_text"]').text("") - $('#hide_no_value').val("Hide No Value") + $('#hideNoValue').val("Hide No Value") tables = ['samples_primary', 'samples_other']; for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; if ($('#' + table).length) { - table_api = $('#' + table).DataTable(); - val_nodes = table_api.column(3).nodes().to$(); + tableApi = $('#' + table).DataTable(); + val_nodes = tableApi.column(3).nodes().to$(); for (i = 0; i < val_nodes.length; i++) { this_node = val_nodes[i].childNodes[0]; this_node.value = this_node.attributes["data-value"].value; } if (js_data.se_exists){ - se_nodes = table_api.column(5).nodes().to$(); + se_nodes = tableApi.column(5).nodes().to$(); for (i = 0; i < val_nodes.length; i++) { this_node = val_nodes[i].childNodes[0]; this_node.value = this_node.attributes["data-value"].value; } } - table_api.draw(); + tableApi.draw(); } } }; $('.reset').click(function() { - reset_samples_table(); + resetSamplesTable(); $('input[name="transform"]').val(""); - edit_data_change(); + editDataChange(); }); -check_for_zero_to_one_vals = function() { +checkForZeroToOneVals = function() { tables = ['samples_primary', 'samples_other']; for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; if ($('#' + table).length) { - table_api = $('#' + table).DataTable(); - val_nodes = table_api.column(3).nodes().to$(); + tableApi = $('#' + table).DataTable(); + val_nodes = tableApi.column(3).nodes().to$(); for (i = 0; i < val_nodes.length; i++) { this_node = val_nodes[i].childNodes[0]; if(!isNaN(this_node.value)) { @@ -943,47 +943,47 @@ check_for_zero_to_one_vals = function() { return false } -log2_data = function(this_node) { +log2Data = function(this_node) { current_value = this_node.value; original_value = this_node.attributes['data-value'].value; if(!isNaN(current_value) && !isNaN(original_value)) { - if (zero_to_one_vals_exist){ + if (zeroToOneValsExist){ original_value = parseFloat(original_value) + 1; } this_node.value = Math.log2(original_value).toFixed(3); } }; -log10_data = function() { +log10Data = function() { current_value = this_node.value; original_value = this_node.attributes['data-value'].value; if(!isNaN(current_value) && !isNaN(original_value)) { - if (zero_to_one_vals_exist){ + if (zeroToOneValsExist){ original_value = parseFloat(original_value) + 1; } this_node.value = Math.log10(original_value).toFixed(3); } }; -sqrt_data = function() { +sqrtData = function() { current_value = this_node.value; original_value = this_node.attributes['data-value'].value; if(!isNaN(current_value) && !isNaN(original_value)) { - if (zero_to_one_vals_exist){ + if (zeroToOneValsExist){ original_value = parseFloat(original_value) + 1; } this_node.value = Math.sqrt(original_value).toFixed(3); } }; -invert_data = function() { +invertData = function() { current_value = this_node.value; if(!isNaN(current_value)) { this_node.value = parseFloat(-(current_value)).toFixed(3); } }; -qnorm_data = function() { +qnormData = function() { current_value = this_node.value; qnorm_value = this_node.attributes['data-qnorm'].value; if(!isNaN(current_value)) { @@ -991,7 +991,7 @@ qnorm_data = function() { } }; -zscore_data = function() { +zScoreData = function() { current_value = this_node.value; zscore_value = this_node.attributes['data-zscore'].value; if(!isNaN(current_value)) { @@ -999,47 +999,47 @@ zscore_data = function() { } }; -do_transform = function(transform_type) { +doTransform = function(transform_type) { tables = ['samples_primary', 'samples_other']; for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; if ($('#' + table).length) { - table_api = $('#' + table).DataTable(); - val_nodes = table_api.column(3).nodes().to$(); + tableApi = $('#' + table).DataTable(); + val_nodes = tableApi.column(3).nodes().to$(); for (i = 0; i < val_nodes.length; i++) { this_node = val_nodes[i].childNodes[0] if (transform_type == "log2"){ - log2_data(this_node) + log2Data(this_node) } if (transform_type == "log10"){ - log10_data(this_node) + log10Data(this_node) } if (transform_type == "sqrt"){ - sqrt_data(this_node) + sqrtData(this_node) } if (transform_type == "invert"){ - invert_data(this_node) + invertData(this_node) } if (transform_type == "qnorm"){ - qnorm_data(this_node) + qnormData(this_node) } if (transform_type == "zscore"){ - zscore_data(this_node) + zScoreData(this_node) } } } } } -normalize_data = function() { +normalizeData = function() { if ($('#norm_method option:selected').val() == 'log2' || $('#norm_method option:selected').val() == 'log10'){ if ($('input[name="transform"]').val() != "log2" && $('#norm_method option:selected').val() == 'log2') { - do_transform("log2") + doTransform("log2") $('input[name="transform"]').val("log2") $('span[name="transform_text"]').text(" - log2 Transformed") } else { if ($('input[name="transform"]').val() != "log10" && $('#norm_method option:selected').val() == 'log10'){ - do_transform("log10") + doTransform("log10") $('input[name="transform"]').val("log10") $('span[name="transform_text"]').text(" - log10 Transformed") } @@ -1047,13 +1047,13 @@ normalize_data = function() { } else if ($('#norm_method option:selected').val() == 'sqrt'){ if ($('input[name="transform"]').val() != "sqrt") { - do_transform("sqrt") + doTransform("sqrt") $('input[name="transform"]').val("sqrt") $('span[name="transform_text"]').text(" - Square Root Transformed") } } else if ($('#norm_method option:selected').val() == 'invert'){ - do_transform("invert") + doTransform("invert") $('input[name="transform"]').val("inverted") if ($('span[name="transform_text"]:eq(0)').text() != ""){ current_text = $('span[name="transform_text"]:eq(0)').text(); @@ -1064,26 +1064,26 @@ normalize_data = function() { } else if ($('#norm_method option:selected').val() == 'qnorm'){ if ($('input[name="transform"]').val() != "qnorm") { - do_transform("qnorm") + doTransform("qnorm") $('input[name="transform"]').val("qnorm") $('span[name="transform_text"]').text(" - Quantile Normalized") } } else if ($('#norm_method option:selected').val() == 'zscore'){ if ($('input[name="transform"]').val() != "zscore") { - do_transform("zscore") + doTransform("zscore") $('input[name="transform"]').val("zscore") $('span[name="transform_text"]').text(" - Z-Scores") } } } -zero_to_one_vals_exist = check_for_zero_to_one_vals(); +zeroToOneValsExist = checkForZeroToOneVals(); -show_transform_warning = function() { +showTransformWarning = function() { transform_type = $('#norm_method option:selected').val() if (transform_type == "log2" || transform_type == "log10"){ - if (zero_to_one_vals_exist){ + if (zeroToOneValsExist){ $('#transform_alert').css("display", "block") } } else { @@ -1092,15 +1092,15 @@ show_transform_warning = function() { } $('#norm_method').change(function(){ - show_transform_warning() + showTransformWarning() }); $('#normalize').hover(function(){ - show_transform_warning() + showTransformWarning() }); -$('#normalize').click(normalize_data) +$('#normalize').click(normalizeData) -switch_qnorm_data = function() { +switchQNormData = function() { return $('.trait-value-input').each((function(_this) { return function(_index, element) { transform_val = $(element).data('transform') @@ -1111,9 +1111,9 @@ switch_qnorm_data = function() { }; })(this)); }; -$('#qnorm').click(switch_qnorm_data); +$('#qnorm').click(switchQNormData); -get_sample_table_data = function(table_name, attributes_as_list) { +getSampleTableData = function(table_name, attributes_as_list) { var samples; samples = []; @@ -1121,22 +1121,22 @@ get_sample_table_data = function(table_name, attributes_as_list) { var n_exists = false; if ($('#' + table_name).length){ - table_api = $('#' + table_name).DataTable(); + tableApi = $('#' + table_name).DataTable(); sample_vals = []; attr_col = 4 - name_nodes = table_api.column(2).nodes().to$(); - val_nodes = table_api.column(3).nodes().to$(); + name_nodes = tableApi.column(2).nodes().to$(); + val_nodes = tableApi.column(3).nodes().to$(); if (js_data.se_exists){ - var_nodes = table_api.column(5).nodes().to$(); + var_nodes = tableApi.column(5).nodes().to$(); attr_col = 6 if (js_data.has_num_cases) { - n_nodes = table_api.column(6).nodes().to$(); + n_nodes = tableApi.column(6).nodes().to$(); attr_col = 7 } } else { if (js_data.has_num_cases){ - n_nodes = table_api.column(4).nodes().to$(); + n_nodes = tableApi.column(4).nodes().to$(); attr_col = 5 } } @@ -1149,13 +1149,13 @@ get_sample_table_data = function(table_name, attributes_as_list) { for (_j = 0; _j < val_nodes.length; _j++){ sample_val = val_nodes[_j].childNodes[0].value sample_name = $.trim(name_nodes[_j].childNodes[0].textContent) - if (is_number(sample_val) && sample_val !== "") { + if (isNumber(sample_val) && sample_val !== "") { sample_val = parseFloat(sample_val); if (typeof var_nodes == 'undefined'){ sample_var = null; } else { sample_var = var_nodes[_j].childNodes[0].value; - if (is_number(sample_var)) { + if (isNumber(sample_var)) { sample_var = parseFloat(sample_var); se_exists = true; } else { @@ -1166,7 +1166,7 @@ get_sample_table_data = function(table_name, attributes_as_list) { sample_n = null; } else { sample_n = n_nodes[_j].childNodes[0].value; - if (is_number(sample_n)) { + if (isNumber(sample_n)) { n_exists = true; sample_n = parseInt(sample_n); } else { @@ -1192,7 +1192,7 @@ get_sample_table_data = function(table_name, attributes_as_list) { return samples; }; -export_sample_table_data = function() { +exportSampleTableData = function() { var format, json_sample_data, sample_data; var attributes_as_list = Object.keys(js_data.attributes).map(function(key) { @@ -1200,8 +1200,8 @@ export_sample_table_data = function() { }); sample_data = {}; - sample_data.primary_samples = get_sample_table_data('samples_primary', attributes_as_list); - sample_data.other_samples = get_sample_table_data('samples_other', attributes_as_list); + sample_data.primary_samples = getSampleTableData('samples_primary', attributes_as_list); + sample_data.other_samples = getSampleTableData('samples_other', attributes_as_list); sample_data.attributes = attributes_as_list; json_sample_data = JSON.stringify(sample_data); $('input[name=export_data]').val(json_sample_data); @@ -1224,11 +1224,11 @@ $('.export_format').change(function() { $('.export_format').val( this.value ); }); -$('.export').click(export_sample_table_data); -$('#block_outliers').click(block_outliers); +$('.export').click(exportSampleTableData); +$('#blockOutliers').click(blockOutliers); _.mixin(_.str.exports()); -get_sample_vals = function(sample_list) { +getSampleVals = function(sample_list) { var sample; return this.sample_vals = (function() { var i, len, results; @@ -1243,7 +1243,7 @@ get_sample_vals = function(sample_list) { })(); }; -get_sample_errors = function(sample_list) { +getSampleErrors = function(sample_list) { var sample; return this.sample_vals = (function() { var i, len, results; @@ -1260,9 +1260,9 @@ get_sample_errors = function(sample_list) { })(); }; -get_sample_names = function(sample_list) { +getSampleNames = function(sample_list) { var sample; - return this.sample_names = (function() { + return this.sampleNames = (function() { var i, len, results; results = []; for (i = 0, len = sample_list.length; i < len; i++) { @@ -1275,31 +1275,31 @@ get_sample_names = function(sample_list) { })(); }; -get_bar_bottom_margin = function(sample_list){ - bottom_margin = 80 - max_length = 0 - sample_names = get_sample_names(sample_list) - for (i=0; i < sample_names.length; i++){ - if (sample_names[i].length > max_length) { - max_length = sample_names[i].length +getBarBottomMargin = function(sample_list){ + bottomMargin = 80 + maxLength = 0 + sampleNames = getSampleNames(sample_list) + for (i=0; i < sampleNames.length; i++){ + if (sampleNames[i].length > maxLength) { + maxLength = sampleNames[i].length } } - if (max_length > 6){ - bottom_margin += 11*(max_length - 6) + if (maxLength > 6){ + bottomMargin += 11*(maxLength - 6) } - return bottom_margin; + return bottomMargin; } root.stats_group = 'samples_primary'; if (Object.keys(js_data.sample_group_types).length > 1) { - full_sample_lists = [sample_lists[0], sample_lists[1], sample_lists[0].concat(sample_lists[1])] - sample_group_list = [js_data.sample_group_types['samples_primary'], js_data.sample_group_types['samples_other'], js_data.sample_group_types['samples_all']] + fullSampleLists = [sampleLists[0], sampleLists[1], sampleLists[0].concat(sampleLists[1])] + sampleGroupList = [js_data.sample_group_types['samples_primary'], js_data.sample_group_types['samples_other'], js_data.sample_group_types['samples_all']] } else { - full_sample_lists = [sample_lists[0]] - sample_group_list = [js_data.sample_group_types['samples_primary']] + fullSampleLists = [sampleLists[0]] + sampleGroupList = [js_data.sample_group_types['samples_primary']] } // Define Plotly Options (for the options bar at the top of each figure) @@ -1328,76 +1328,76 @@ root.modebar_options = { // Bar Chart -root.errors_exist = get_sample_errors(sample_lists[0])[1] -var bar_trace = { - x: get_sample_names(sample_lists[0]), - y: get_sample_vals(sample_lists[0]), +root.errors_exist = getSampleErrors(sampleLists[0])[1] +var barTrace = { + x: getSampleNames(sampleLists[0]), + y: getSampleVals(sampleLists[0]), error_y: { type: 'data', - array: get_sample_errors(sample_lists[0])[0], + array: getSampleErrors(sampleLists[0])[0], visible: root.errors_exist }, type: 'bar' } -root.bar_data = [bar_trace] +root.bar_data = [barTrace] -get_bar_range = function(sample_vals, sample_errors = null){ - positive_error_vals = [] - negative_error_vals = [] +getBarRange = function(sample_vals, sampleErrors = null){ + positiveErrorVals = [] + negativeErrorVals = [] for (i = 0;i < sample_vals.length; i++){ - if (sample_errors[i] != undefined) { - positive_error_vals.push(sample_vals[i] + sample_errors[i]) - negative_error_vals.push(sample_vals[i] - sample_errors[i]) + if (sampleErrors[i] != undefined) { + positiveErrorVals.push(sample_vals[i] + sampleErrors[i]) + negativeErrorVals.push(sample_vals[i] - sampleErrors[i]) } else { - positive_error_vals.push(sample_vals[i]) - negative_error_vals.push(sample_vals[i]) + positiveErrorVals.push(sample_vals[i]) + negativeErrorVals.push(sample_vals[i]) } } - min_y_val = Math.min(...negative_error_vals) - max_y_val = Math.max(...positive_error_vals) + minYVal = Math.min(...negativeErrorVals) + maxYVal = Math.max(...positiveErrorVals) - if (min_y_val == 0) { - range_top = max_y_val + Math.abs(max_y_val)*0.1 - range_bottom = 0; + if (minYVal == 0) { + rangeTop = maxYVal + Math.abs(maxYVal)*0.1 + rangeBottom = 0; } else { - range_top = max_y_val + Math.abs(max_y_val)*0.1 - range_bottom = min_y_val - Math.abs(min_y_val)*0.1 - if (min_y_val > 0) { - range_bottom = min_y_val - 0.1*Math.abs(min_y_val) - } else if (min_y_val < 0) { - range_bottom = min_y_val + 0.1*min_y_val + rangeTop = maxYVal + Math.abs(maxYVal)*0.1 + rangeBottom = minYVal - Math.abs(minYVal)*0.1 + if (minYVal > 0) { + rangeBottom = minYVal - 0.1*Math.abs(minYVal) + } else if (minYVal < 0) { + rangeBottom = minYVal + 0.1*minYVal } else { - range_bottom = 0 + rangeBottom = 0 } } - return [range_bottom, range_top] + return [rangeBottom, rangeTop] } -root.chart_range = get_bar_range(get_sample_vals(sample_lists[0]), get_sample_errors(sample_lists[0])[0]) -val_range = root.chart_range[1] - root.chart_range[0] - -if (val_range < 0.05){ - tick_digits = '.3f' - left_margin = 80 -} else if (val_range < 0.5) { - tick_digits = '.2f' - left_margin = 70 -} else if (val_range < 5){ - tick_digits = '.1f' - left_margin = 60 +root.chart_range = getBarRange(getSampleVals(sampleLists[0]), getSampleErrors(sampleLists[0])[0]) +valRange = root.chart_range[1] - root.chart_range[0] + +if (valRange < 0.05){ + tickDigits = '.3f' + leftMargin = 80 +} else if (valRange < 0.5) { + tickDigits = '.2f' + leftMargin = 70 +} else if (valRange < 5){ + tickDigits = '.1f' + leftMargin = 60 } else { - tick_digits = 'f' - left_margin = 55 + tickDigits = 'f' + leftMargin = 55 } if (js_data.num_values < 256) { - bar_chart_width = 25 * get_sample_vals(sample_lists[0]).length + barChartWidth = 25 * getSampleVals(sampleLists[0]).length //ZS: Set bottom margin dependent on longest sample name length, since those can get long - bottom_margin = get_bar_bottom_margin(sample_lists[0]) + bottomMargin = getBarBottomMargin(sampleLists[0]) root.bar_layout = { title: "<b>Trait " + js_data.trait_id + ": " + js_data.short_description + "</b>", @@ -1423,32 +1423,32 @@ if (js_data.num_values < 256) { tickfont: { size: 16 }, - tickformat: tick_digits, + tickformat: tickDigits, fixedrange: true }, - width: bar_chart_width, + width: barChartWidth, height: 600, margin: { - l: left_margin, + l: leftMargin, r: 30, t: 100, - b: bottom_margin + b: bottomMargin } }; $('.bar_chart_tab').click(function() { - update_bar_chart(); + updateBarChart(); }); } total_sample_count = 0 -for (i = 0, i < sample_lists.length; i++;) { - total_sample_count += get_sample_vals(sample_lists[i]).length +for (i = 0, i < sampleLists.length; i++;) { + total_sample_count += getSampleVals(sampleLists[i]).length } // Histogram var hist_trace = { - x: get_sample_vals(sample_lists[0]), + x: getSampleVals(sampleLists[0]), type: 'histogram' }; root.histogram_data = [hist_trace]; @@ -1493,14 +1493,14 @@ root.histogram_layout = { }; $('.histogram_tab').click(function() { - update_histogram(); - update_histogram_width(); + updateHistogram(); + updateHistogram_width(); }); $('.histogram_samples_group').val(root.stats_group); $('.histogram_samples_group').change(function() { root.stats_group = $(this).val(); - return update_histogram(); + return updateHistogram(); }); root.box_layout = { @@ -1526,7 +1526,7 @@ root.box_layout = { tickfont: { size: 16 }, - tickformat: tick_digits, + tickformat: tickDigits, zeroline: false, automargin: true }, @@ -1537,13 +1537,13 @@ root.box_layout = { b: 80 } }; -if (full_sample_lists.length > 1) { +if (fullSampleLists.length > 1) { root.box_layout['width'] = 600; root.box_layout['height'] = 500; var trace1 = { - y: get_sample_vals(full_sample_lists[0]), + y: getSampleVals(fullSampleLists[0]), type: 'box', - name: sample_group_list[0], + name: sampleGroupList[0], boxpoints: 'Outliers', jitter: 0.5, whiskerwidth: 0.2, @@ -1558,9 +1558,9 @@ if (full_sample_lists.length > 1) { } } var trace2 = { - y: get_sample_vals(full_sample_lists[1]), + y: getSampleVals(fullSampleLists[1]), type: 'box', - name: sample_group_list[1], + name: sampleGroupList[1], boxpoints: 'Outliers', jitter: 0.5, whiskerwidth: 0.2, @@ -1575,9 +1575,9 @@ if (full_sample_lists.length > 1) { } } var trace3 = { - y: get_sample_vals(full_sample_lists[2]), + y: getSampleVals(fullSampleLists[2]), type: 'box', - name: sample_group_list[2], + name: sampleGroupList[2], boxpoints: 'Outliers', jitter: 0.5, whiskerwidth: 0.2, @@ -1598,7 +1598,7 @@ if (full_sample_lists.length > 1) { root.box_data = [ { type: 'box', - y: get_sample_vals(full_sample_lists[0]), + y: getSampleVals(fullSampleLists[0]), name: "<b>Trait " + js_data.trait_id + "</b>", boxpoints: 'Outliers', jitter: 0.5, @@ -1649,7 +1649,7 @@ root.violin_layout = { tickfont: { size: 16 }, - tickformat: tick_digits, + tickformat: tickDigits, zeroline: false, automargin: true }, @@ -1661,11 +1661,11 @@ root.violin_layout = { } }; -if (full_sample_lists.length > 1) { +if (fullSampleLists.length > 1) { root.violin_layout['width'] = 600; root.violin_layout['height'] = 500; var trace1 = { - y: get_sample_vals(full_sample_lists[2]), + y: getSampleVals(fullSampleLists[2]), type: 'violin', points: 'none', box: { @@ -1677,11 +1677,11 @@ if (full_sample_lists.length > 1) { meanline: { visible: true }, - name: sample_group_list[2], - x0: sample_group_list[2] + name: sampleGroupList[2], + x0: sampleGroupList[2] } var trace2 = { - y: get_sample_vals(full_sample_lists[1]), + y: getSampleVals(fullSampleLists[1]), type: 'violin', points: 'none', box: { @@ -1693,11 +1693,11 @@ if (full_sample_lists.length > 1) { meanline: { visible: true }, - name: sample_group_list[1], - x0: sample_group_list[1] + name: sampleGroupList[1], + x0: sampleGroupList[1] } var trace3 = { - y: get_sample_vals(full_sample_lists[0]), + y: getSampleVals(fullSampleLists[0]), type: 'violin', points: 'none', box: { @@ -1709,8 +1709,8 @@ if (full_sample_lists.length > 1) { meanline: { visible: true }, - name: sample_group_list[0], - x0: sample_group_list[0] + name: sampleGroupList[0], + x0: sampleGroupList[0] } root.violin_data = [trace1, trace2, trace3] } else { @@ -1718,7 +1718,7 @@ if (full_sample_lists.length > 1) { root.violin_layout['height'] = 400; root.violin_data = [ { - y: get_sample_vals(full_sample_lists[0]), + y: getSampleVals(fullSampleLists[0]), type: 'violin', points: 'none', box: { @@ -1734,33 +1734,33 @@ if (full_sample_lists.length > 1) { } $('.violin_plot_tab').click(function() { - update_violin_plot(); + updateViolinPlot(); }); -if (get_sample_vals(sample_lists[0]).length < 256) { +if (getSampleVals(sampleLists[0]).length < 256) { $('.bar_chart_samples_group').change(function() { root.stats_group = $(this).val(); - return update_bar_chart(); + return updateBarChart(); }); root.bar_sort = "name" } $('.sort_by_name').click(function() { root.bar_sort = "name" - return update_bar_chart(); + return updateBarChart(); }); $('.sort_by_value').click(function() { root.bar_sort = "value" - return update_bar_chart(); + return updateBarChart(); }); root.prob_plot_group = 'samples_primary'; $('.prob_plot_samples_group').val(root.prob_plot_group); $('.prob_plot_tab').click(function() { - return update_prob_plot(); + return updateProbPlot(); }); $('.prob_plot_samples_group').change(function() { root.prob_plot_group = $(this).val(); - return update_prob_plot(); + return updateProbPlot(); }); function isEmpty( el ){ @@ -1769,37 +1769,37 @@ function isEmpty( el ){ $('.stats_panel').click(function() { if (isEmpty($('#stats_table'))){ - make_table(); - edit_data_change(); + makeTable(); + editDataChange(); } else { - edit_data_change(); + editDataChange(); } }); -$('#block_by_index').click(function(){ - block_by_index(); - edit_data_change(); +$('#blockByIndex').click(function(){ + blockByIndex(); + editDataChange(); }); $('#filter_by_study').click(function(){ filter_by_study(); - edit_data_change(); + editDataChange(); }) $('#filter_by_value').click(function(){ filter_by_value(); - edit_data_change(); + editDataChange(); }) $('.edit_sample_value').change(function() { - edit_data_change(); + editDataChange(); }); -$('#exclude_group').click(edit_data_change); -$('#block_outliers').click(edit_data_change); -$('#reset').click(edit_data_change); -$('#qnorm').click(edit_data_change); -$('#normalize').click(edit_data_change); +$('#exclude_group').click(editDataChange); +$('#blockOutliers').click(editDataChange); +$('#reset').click(editDataChange); +$('#qnorm').click(editDataChange); +$('#normalize').click(editDataChange); Number.prototype.countDecimals = function () { if(Math.floor(this.valueOf()) === this.valueOf()) return 0; diff --git a/wqflask/wqflask/static/new/javascript/table_functions.js b/wqflask/wqflask/static/new/javascript/table_functions.js index 745563c2..ea2cf60c 100644 --- a/wqflask/wqflask/static/new/javascript/table_functions.js +++ b/wqflask/wqflask/static/new/javascript/table_functions.js @@ -1,36 +1,36 @@ -recheck_rows = function(the_table, checked_rows){ - //ZS: This is meant to recheck checkboxes after columns are resized - check_cells = the_table.column(0).nodes().to$(); - for (let i = 0; i < check_cells.length; i++) { - if (checked_rows.includes(i)){ - check_cells[i].childNodes[0].checked = true; +recheckRows = function(theTable, checkedRows){ + // This is meant to recheck checkboxes after columns are resized + checkCells = theTable.column(0).nodes().to$(); + for (let i = 0; i < checkCells.length; i++) { + if (checkedRows.includes(i)){ + checkCells[i].childNodes[0].checked = true; } } - check_rows = trait_table.rows().nodes(); - for (let i =0; i < check_rows.length; i++) { - if (checked_rows.includes(i)){ - check_rows[i].classList.add("selected") + checkRows = traitTable.rows().nodes(); + for (let i =0; i < checkRows.length; i++) { + if (checkedRows.includes(i)){ + checkRows[i].classList.add("selected") } } } -get_checked_rows = function(table_id){ - let checked_rows = [] - $("#" + table_id + " input").each(function(index){ +getCheckedRows = function(tableId){ + let checkedRows = [] + $("#" + tableId + " input").each(function(index){ if ($(this).prop("checked") == true){ - checked_rows.push(index); + checkedRows.push(index); } }); - return checked_rows + return checkedRows } -function setUserColumnsDefWidths(table_id) { +function setUserColumnsDefWidths(tableId, columnDefs) { var userColumnDef; // Get the settings for this table from localStorage - var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; if (userColumnDefs.length === 0 ) return; @@ -57,13 +57,15 @@ function setUserColumnsDefWidths(table_id) { }) } }); + + return columnDefs } -function saveColumnSettings(table_id, trait_table) { - var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; +function saveColumnSettings(tableId, traitTable) { + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; var width, header, existingSetting; - trait_table.columns().every( function ( targets ) { + traitTable.columns().every( function ( targets ) { // Check if there is a setting for this column in localStorage existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); @@ -84,5 +86,5 @@ function saveColumnSettings(table_id, trait_table) { }); // Save (or update) the settings in localStorage - localStorage.setItem(table_id, JSON.stringify(userColumnDefs)); + localStorage.setItem(tableId, JSON.stringify(userColumnDefs)); } diff --git a/wqflask/wqflask/submit_bnw.py b/wqflask/wqflask/submit_bnw.py deleted file mode 100644 index b21a88cc..00000000 --- a/wqflask/wqflask/submit_bnw.py +++ /dev/null @@ -1,10 +0,0 @@ -from base.trait import GeneralTrait -from base import data_set -from utility import helper_functions - -import utility.logger -logger = utility.logger.getLogger(__name__) - - -def get_bnw_input(start_vars): - logger.debug("BNW VARS:", start_vars) diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html index 6e1261d7..1a125dbb 100644 --- a/wqflask/wqflask/templates/collections/list.html +++ b/wqflask/wqflask/templates/collections/list.html @@ -75,44 +75,22 @@ <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='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> <script type="text/javascript" src="/static/new/javascript/search_results.js"></script> + <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script> - $('#trait_table').dataTable( { - "drawCallback": function( settings ) { - $('#trait_table tr').click(function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - }); - }, - "buttons": [ 'copy', 'csv', 'excel' ], - "columns": [ - { "type": "natural", "width": "3%" }, - { "type": "natural", "width": "8%" }, - { "type": "natural", "width": "20%" }, - { "type": "natural", "width": "25%" }, - { "type": "natural", "width": "25%" }, - { "type": "natural", "width": "15%" } - ], - "columnDefs": [ { - "targets": 0, - "orderable": false - } ], - "order": [[1, "asc" ]], - "sDom": "BZtr", - "iDisplayLength": -1, - "autoWidth": false, - "bDeferRender": true, - "bSortClasses": false, - "scrollCollapse": true, - "paging": false, - "orderClasses": true - } ); + $(document).ready( function () { + tableId = "trait_table"; + + columnDefs = [ + { "type": "natural", "width": "3%", "targets": 0, "orderable": false}, + { "type": "natural", "width": "8%", "targets": 1}, + { "type": "natural", "width": "20%", "targets": 2}, + { "type": "natural", "width": "25%", "targets": 3}, + { "type": "natural", "width": "25%", "targets": 4}, + { "type": "natural", "width": "15%", "targets": 5} + ]; + + create_table(tableId, [], columnDefs) submit_special = function(url) { $("#collections_form").attr("action", url); @@ -167,6 +145,7 @@ return submit_special(url) }); + }); </script> {% endblock %} diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html index 2f385987..643d6f31 100644 --- a/wqflask/wqflask/templates/collections/view.html +++ b/wqflask/wqflask/templates/collections/view.html @@ -3,6 +3,7 @@ {% block css %} <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}"> + <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" /> {% endblock %} @@ -19,7 +20,7 @@ <h3>This collection has {{ '{}'.format(numify(trait_obs|count, "record", "records")) }}</h3> <div class="tool-button-container"> - <form id="collection_form" action="/delete" method="post"> + <form id="collection_form" action="/loading" method="post"> <input type="hidden" name="uc_id" id="uc_id" value="{{ uc.id }}" /> <input type="hidden" name="collection_name" id="collection_name" value="{{ uc.name }}" /> <input type="hidden" name="tool_used" value="" /> @@ -93,74 +94,11 @@ <div style="margin-top: 10px; margin-bottom: 5px;"> <b>Show/Hide Columns:</b> </div> - <div style="min-width: 1500px;"> + <div id="trait_table_container" style="width: 2000px; min-width: 1500px;"> <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;"> - <thead> - <tr> - <th></th> - <th data-export="Index">Index</th> - <th data-export="Dataset">Dataset</th> - <th data-export="Record">Record</th> - <th data-export="Symbol">Symbol</th> - <th data-export="Description">Description</th> - <th data-export="Location">Location</th> - <th data-export="Mean">Mean</th> - <th data-export="Max LRS">High P <a href="{{ url_for('glossary_blueprint.glossary') }}#L" target="_blank"><sup style="font-size: small; color: #FF0000;"> ?</sup></a></th> - <th data-export="Peak Location">Peak Location</th> - <th data-export="Add. Eff.">Effect Size <a href="{{ url_for('glossary_blueprint.glossary') }}#A" target="_blank"><sup style="font-size: small; color: #FF0000;"> ?</sup></a></th> - </tr> - </thead> - <tbody> - {% for this_trait in trait_obs %} - <TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}"> - <TD align="center" style="padding: 0px;"><input type="checkbox" - name="searchResult" - class="checkbox trait_checkbox" - value="{{data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name))}}" - data-trait-info="{{trait_info_str(this_trait)}}"> - </TD> - <TD data-export="{{ loop.index }}" align="right">{{ loop.index }}</TD> - <TD title="{{ this_trait.dataset.fullname }}" data-export="{{ this_trait.dataset.fullname }}">{{ this_trait.dataset.fullname }}</TD> - <TD data-export="{{ this_trait.name }}"> - <a href="{{ url_for('show_trait_page', - trait_id = this_trait.name, - dataset = this_trait.dataset.name - )}}"> - {{ this_trait.display_name }} - </a> - </TD> - {% if this_trait.symbol %} - <TD title="{{ this_trait.symbol }}" data-export="{{ this_trait.symbol }}">{% if this_trait.symbol|length > 20 %}{{ this_trait.symbol[:20] }}...{% else %}{{ this_trait.symbol }}{% endif %}</TD> - {% elif this_trait.abbreviation %} - <TD title="{{ this_trait.abbreviation }}" data-export="{{ this_trait.abbreviation }}">{% if this_trait.abbreviation|length > 20 %}{{ this_trait.abbreviation[:20] }}...{% else %}{{ this_trait.abbreviation }}{% endif %}</TD> - {% else %} - <TD data-export="N/A">N/A</TD> - {% endif %} - {% if this_trait.dataset.type == "Geno" %} - <TD title="Marker: {{ this_trait.name }}" data-export="Marker: {{ this_trait.name }}">Marker: {{ this_trait.name }}</TD> - {% elif this_trait.description_display != "" %} - <TD title="{{ this_trait.description_display }}" data-export="{{ this_trait.description_display }}">{{ this_trait.description_display }}</TD> - {% else %} - <TD title="N/A" data-export="N/A">N/A</TD> - {% endif %} - <TD data-export="{{ this_trait.location_repr }}">{{ this_trait.location_repr }}</TD> - <TD data-export="{{ this_trait.mean }}" align="right">{{ '%0.3f' % this_trait.mean|float }}</TD> - {% if this_trait.LRS_score_repr|float > 0 %} - <TD data-export="{{ this_trait.LRS_score_repr }}" align="right">{{ '%0.3f' % this_trait.LRS_score_repr|float }}</TD> - {% else %} - <TD data-export="{{ this_trait.LRS_score_repr }}" align="right">N/A</TD> - {% endif %} - <TD data-export="{{ this_trait.LRS_location_repr }}">{{ this_trait.LRS_location_repr }}</TD> - {% if this_trait.additive|float != 0 %} - <TD data-export="{{ this_trait.additive }}" align="right">{{ '%0.3f' % this_trait.additive|float }}</TD> - {% else %} - <TD data-export="{{ this_trait.additive }}" align="right">N/A</TD> - {% endif %} - </TR> - {% endfor %} + <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td> </tbody> - </table> </div> <br /> @@ -175,70 +113,199 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script> <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/scroller/js/dataTables.scroller.min.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='DataTablesExtensions/colResize/dataTables.colResize.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colReorder/js/dataTables.colReorder.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/buttons.colVis.min.js') }}"></script> <script type="text/javascript" src="/static/new/javascript/search_results.js"></script> + <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script> <script type="text/javascript" src="/static/new/javascript/partial_correlations.js"></script> - - + <script type='text/javascript'> + var traitsJson = {{ traits_json|safe }}; + </script> <script language="javascript" type="text/javascript"> $(document).ready( function () { - $('#trait_table').dataTable( { - 'drawCallback': function( settings ) { - $('#trait_table tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); + + tableId = "trait_table" + + columnDefs = [ + { + 'data': null, + 'width': "5px", + 'orderDataType': "dom-checkbox", + 'targets': 0, + 'render': function(data) { + return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '" data-trait-info="' + data.trait_info_str + '">' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "35px", + 'searchable': false, + 'orderable': false, + 'targets': 1, + 'render': function(data, type, row, meta) { + return meta.row + } + }, + { + 'title': "Dataset", + 'type': "natural", + 'targets': 2, + 'data': "dataset" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'width': "120px", + 'targets': 3, + 'data': null, + 'render': function(data) { + return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' + } + }, + { + 'title': "Symbol", + 'type': "natural", + 'targets': 4, + 'data': null, + 'render': function(data) { + if (Object.hasOwn(data, 'symbol')){ + return data.symbol + } else { + return "N/A" } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") + } + }, + { + 'title': "Description", + 'type': "natural", + 'targets': 5, + 'data': null, + 'render': function(data) { + if (Object.hasOwn(data, 'description')){ + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) + } + } else { + return "N/A" } - change_buttons() - }); + } }, - "columns": [ - { - "orderDataType": "dom-checkbox", - "orderSequence": [ "desc", "asc"], - "width": 10 - }, - { "type": "natural", "width": 50 }, - { "type": "natural" }, - { 'type': "natural-minus-na", "width": 120 }, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural", "width": 125 }, - { "type": "natural", "width": 60 }, - { "type": "natural", "width": 60 }, - { "type": "natural", "width": 125 }, - { "type": "natural", "width": 85 } - ], - "order": [[1, "asc" ]], - buttons: [ - { - extend: 'columnsToggle', - columns: ':not(:first-child)', - postfixButtons: [ 'colvisRestore' ] + { + 'title': "<div style='text-align: right;'>Location</div>", + 'type': "natural-minus-na", + 'width': "125px", + 'targets': 6, + 'data': null, + 'render': function(data) { + if (Object.hasOwn(data, 'location')){ + return data.location + } else { + return "N/A" + } } - ], - "sDom": "BZRtr", - "iDisplayLength": -1, - "autoWidth": false, - "bDeferRender": true, - "bSortClasses": false, - "paging": false, - "orderClasses": true - } ); - + }, + { + 'title': "<div style='text-align: right;'>Mean</div>", + 'type': "natural-minus-na", + 'width': "60px", + 'data': null, + 'targets': 7, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (Object.hasOwn(data, 'mean')){ + return data.mean.toFixed(3) + } else { + return "N/A" + } + } + }, + { + 'title': "<div style='text-align: right; padding-right: 10px;'>Peak</div> <div style='text-align: right;'>LOD <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'targets': 8, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (Object.hasOwn(data, 'lrs_score')){ + return (data.lrs_score / 4.61).toFixed(3) + } else { + return "N/A" + } + } + }, + { + 'title': "<div style='text-align: right;'>Peak Location</div>", + 'type': "natural-minus-na", + 'data': null, + 'width': "125px", + 'targets': 9, + 'render': function(data) { + if (Object.hasOwn(data, 'lrs_location')){ + return data.lrs_location + } else { + return "N/A" + } + } + }, + { + 'title': "<div style='text-align: right; padding-right: 10px;'>Effect</div> <div style='text-align: right;'>Size <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"><sup style='color: #FF0000;'><i>?</i></sup></a></div>", + 'type': "natural-minus-na", + 'data': null, + 'width': "85px", + 'targets': 10, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (Object.hasOwn(data, 'additive')){ + return data.additive.toFixed(3) + } else { + return "N/A" + } + } + } + ] + + tableSettings = { + "createdRow": function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + if ($('td', row).eq(5).text().length > 500) { + $('td', row).eq(5).text($('td', row).eq(5).text().substring(0, 500)); + $('td', row).eq(5).text($('td', row).eq(5).text() + '...') + } + $('td', row).slice(6,11).attr("align", "right"); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); + $('td', row).eq(10).attr('data-export', $('td', row).eq(9).text()); + }, + "order": [[1, "asc" ]], + {% if traits_json|length > 20 %} + "scroller": true + {% else %} + "scroller": false + {% endif %} + } + + create_table(tableId, traitsJson, columnDefs, tableSettings) submit_special = function(url) { $("#collection_form").attr("action", url); diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index ceaa34b1..c6cd2544 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -131,9 +131,6 @@ {% endblock %} {% block js %} - <script type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script> - <script type="text/javascript" src="/static/new/javascript/search_results.js"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script> @@ -143,10 +140,13 @@ <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='fontawesome/js/all.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> + <script type="text/javascript" src="/static/new/javascript/search_results.js"></script> + <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script type="text/javascript" charset="utf-8"> - var table_json = {{ table_json | safe }} + var tableJson = {{ table_json | safe }} </script> <script type="text/javascript" charset="utf-8"> @@ -223,370 +223,329 @@ {% endif %} $(document).ready( function () { - table_conf = { - buttons: [ - { - extend: 'csvHtml5', - text: 'Download <span class="glyphicon glyphicon-download"></span>', - className: 'btn btn-default', - exportOptions: { - columns: 'th:not(:first-child)' - } - } - ], - 'drawCallback': function( settings ) { - $('#trait_table tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - "data": table_json, - "columns": [ - { - 'data': null, - 'width': "25px", - 'orderDataType': "dom-checkbox", - 'orderSequence': [ "desc", "asc"], - 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '">' - } - }, - { - 'title': "Index", - 'type': "natural", - 'width': "30px", - 'data': "index" - }, - { - 'title': "Record", - 'type': "natural-minus-na", - 'data': null, - 'width': "60px", - 'render': function(data, type, row, meta) { - return '<a target="_blank" href="/show_trait?trait_id=' + data.trait_id + '&dataset=' + data.dataset + '">' + data.trait_id + '</a>' - } - }{% if target_dataset.type == 'ProbeSet' %}, - { - 'title': "Symbol", - 'type': "natural", - 'width': "120px", - 'data': "symbol" - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return escape(data.description) - } - } - }, - { - 'title': "Location", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "location" - }, - { - 'title': "Mean", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}", - 'type': "natural-minus-na", - 'width': "40px", - 'data': null, - '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 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 - } - } - }, - { - 'title': "N", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "num_overlap", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})", - 'type': "scientific", - 'width': "65px", - 'data': "sample_p", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Lit {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "lit_corr", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Tissue {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "tissue_corr", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Tissue p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "tissue_pvalue", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Peak Location", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "85px", - 'orderSequence': [ "desc", "asc"] - }{% elif target_dataset.type == 'Publish' %}, - { - 'title': "Abbreviation", - 'type': "natural", - 'width': "200px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.abbreviation_display)) - } catch(err){ - return data.abbreviation_display - } - } - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return data.description - } - } - }, - { - 'title': "Mean", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Authors", - 'type': "natural", - 'width': "400px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.authors_display)) - } catch(err){ - return data.authors_display - } - } - }, - { - 'title': "Year", - 'type': "natural-minus-na", - 'data': null, - 'width': "80px", - 'render': function(data, type, row, meta) { - if (data.pubmed_id != "N/A"){ - return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>' - } else { - return data.pubmed_text - } - }, - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}", - 'type': "natural-minus-na", - 'width': "40px", - 'data': null, - '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 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 - } - } - }, - { - 'title': "N", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "num_overlap", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})", - 'type': "scientific", - 'width': "65px", - 'data': "sample_p", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Peak Location", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "85px", - 'orderSequence': [ "desc", "asc"] - }{% elif target_dataset.type == 'Geno' %}, - { - 'title': "Location", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "location" - }, - { - 'title': "Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}", - 'type': "natural-minus-na", - 'width': "40px", - 'data': null, - '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 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 - } - } - }, - { - 'title': "N", - 'type': "natural-minus-na", - 'width': "40px", - 'data': "num_overlap", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})", - 'type': "scientific", - 'width': "65px", - 'data': "sample_p", - 'orderSequence': [ "desc", "asc"] - }{% endif %} - ], - "columnDefs": [ { - "targets": 0, - "orderable": false - } ], - {% if target_dataset.type == 'Geno' %} - "order": [[6, "asc" ]], - {% elif target_dataset.type == 'Publish' %} - "order": [[10, "asc" ]], - {% else %} - "order": [[9, "asc" ]], - {% endif %} - "sDom": "itir", - "autoWidth": true, - "bSortClasses": false, - "scrollY": "100vh", - "scroller": true, - "scrollCollapse": true - } - - trait_table = $('#trait_table').DataTable(table_conf); - trait_table.buttons().container().appendTo('#export_options') + tableId = "trait_table"; - $('.buttons-csv').removeClass('dt-button') - - trait_table.on( 'order.dt search.dt draw.dt', function () { - trait_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { - cell.innerHTML = i+1; - } ); - } ).draw(); + {% if corr_method == 'pearson' %} + rOrRho = "r" + corr_method = "pearson" + {% else %} + rOrRho = "rho" + corr_method = "spearman" + {% endif %} - $('.toggle-vis').on('click', function (e) { - e.preventDefault(); + columnDefs = [ + { + 'data': null, + 'width': "25px", + 'orderDataType': "dom-checkbox", + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '">' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "30px", + 'data': "index" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'render': function(data) { + return '<a target="_blank" href="/show_trait?trait_id=' + data.trait_id + '&dataset=' + data.dataset + '">' + data.trait_id + '</a>' + } + }{% if target_dataset.type == 'ProbeSet' %}, + { + 'title': "Symbol", + 'type': "natural", + 'width': "120px", + 'data': "symbol" + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'render': function(data) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) + } + } + }, + { + 'title': "Location", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "location" + }, + { + 'title': "Mean", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Sample " + rOrRho, + 'type': "natural-minus-na", + 'width': "40px", + 'data': null, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (data.sample_r != "N/A") { + return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&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 + } + } + }, + { + 'title': "N", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "num_overlap", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Sample p(" + rOrRho + ")", + 'type': "scientific", + 'width': "65px", + 'data': "sample_p", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Lit " + rOrRho, + 'type': "natural-minus-na", + 'width': "40px", + 'data': "lit_corr", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Tissue " + rOrRho, + 'type': "natural-minus-na", + 'width': "40px", + 'data': "tissue_corr", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Tissue p(" + rOrRho + ")", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "tissue_pvalue", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Peak Location", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "lrs_location" + }, + { + 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "85px", + 'orderSequence': [ "desc", "asc"] + }{% elif target_dataset.type == 'Publish' %}, + { + 'title': "Abbreviation", + 'type': "natural", + 'width': "200px", + 'data': null, + 'render': function(data) { + try { + return decodeURIComponent(escape(data.abbreviation_display)) + } catch(err){ + return data.abbreviation_display + } + } + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'render': function(data) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return data.description + } + } + }, + { + 'title': "Mean", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Authors", + 'type': "natural", + 'width': "400px", + 'data': null, + 'render': function(data) { + try { + return decodeURIComponent(escape(data.authors_display)) + } catch(err){ + return data.authors_display + } + } + }, + { + 'title': "Year", + 'type': "natural-minus-na", + 'data': null, + 'width': "80px", + 'render': function(data) { + if (data.pubmed_id != "N/A"){ + return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>' + } else { + return data.pubmed_text + } + }, + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Sample " + rOrRho, + 'type': "natural-minus-na", + 'width': "40px", + 'data': null, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (data.sample_r != "N/A") { + return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&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 + } + } + }, + { + 'title': "N", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "num_overlap", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Sample p(" + rOrRho + ")", + 'type': "scientific", + 'width': "65px", + 'data': "sample_p", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Peak Location", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "lrs_location" + }, + { + 'title': "Effect Size<a href=\"http://gn1.genenetwork.org/glossary.html#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "85px", + 'orderSequence': [ "desc", "asc"] + }{% elif target_dataset.type == 'Geno' %}, + { + 'title': "Location", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "location" + }, + { + 'title': "Sample " + rOrRho, + 'type': "natural-minus-na", + 'width': "40px", + 'data': null, + 'orderSequence': [ "desc", "asc"], + 'render': function(data) { + if (data.sample_r != "N/A") { + return "<a target\"_blank\" href=\"corr_scatter_plot?method=" + corr_method + "&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 + } + } + }, + { + 'title': "N", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "num_overlap", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Sample p(" + rOrRho + ")", + 'type': "scientific", + 'width': "65px", + 'data': "sample_p", + 'orderSequence': [ "desc", "asc"] + }{% endif %} + ] - // Get the column API object - var column = trait_table.column( $(this).attr('data-column') ); + tableSettings = { + "buttons": [ + { + extend: 'csvHtml5', + text: 'Download <span class="glyphicon glyphicon-download"></span>', + className: 'btn btn-default', + exportOptions: { + columns: 'th:not(:first-child)' + } + } + ], + {% if target_dataset.type == 'Geno' %} + "order": [[6, "asc" ]], + {% elif target_dataset.type == 'Publish' %} + "order": [[10, "asc" ]], + {% else %} + "order": [[9, "asc" ]], + {% endif %} + } - // Toggle the visibility - column.visible( ! column.visible() ); + create_table(tableId, tableJson, columnDefs, tableSettings) - if (column.visible()){ - $(this).removeClass("active"); - } else { - $(this).addClass("active"); - } - } ); + trait_table = $('#trait_table').DataTable(); + trait_table.buttons().container().appendTo('#export_options') - $('#redraw').on('click', function (e) { - e.preventDefault(); - trait_table.columns().visible( true ); - $('.toggle-vis.active').removeClass('active'); - }); + $('.buttons-csv').removeClass('dt-button') - submit_special = function(url) { - $("#correlation_form").attr("action", url); - return $("#correlation_form").submit(); - }; + submit_special = function(url) { + $("#correlation_form").attr("action", url); + return $("#correlation_form").submit(); + }; - $("#delete").on("click", function() { - url = $(this).data("url") - return submit_special(url) - }); + $("#delete").on("click", function() { + url = $(this).data("url") + return submit_special(url) + }); - $("#more_options").click(function() { - $("div#filter_options").toggle(); - }); + $("#more_options").click(function() { + $("div#filter_options").toggle(); + }); - $("#select_traits").click(function() { - console.log("redrawing") - trait_table.draw(); - }); + $("#select_traits").click(function() { + trait_table.draw(); + }); }); </script> {% endblock %} diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index 69281ec5..39c46f02 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -56,6 +56,7 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colResize/dataTables.colResize.js') }}"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script type='text/javascript'> var getParams = function(url) { @@ -70,22 +71,20 @@ </script> <script type='text/javascript'> - var trait_list = {{ trait_list|safe }}; + var traitsJson = {{ trait_list|safe }}; </script> <script type="text/javascript" charset="utf-8"> $(document).ready( function () { 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 - columnDefs = [ { 'orderDataType': "dom-checkbox", 'width': "5px", 'data': null, 'targets': 0, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<input type="checkbox" name="searchResult" class="trait_checkbox checkbox" value="' + data.hmac + '">' } }, @@ -103,7 +102,7 @@ 'width': "60px", 'data': null, 'targets': 2, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.name + '</a>' } }, @@ -148,7 +147,7 @@ 'data': null, 'width': "120px", 'targets': 8, - 'render': function(data, type, row, meta) { + 'render': function(data) { try { return decodeURIComponent(escape(data.description)) } catch(err) { @@ -196,30 +195,8 @@ } ] - loadDataTable(true); - - function loadDataTable(first_run=false){ - - if (!first_run){ - setUserColumnsDefWidths(tableId); - } - - table_settings = { - 'drawCallback': function( settings ) { - $('#' + tableId + ' tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - 'createdRow': function ( row, data, index ) { + tableSettings = { + 'createdRow': function ( row, data, index ) { $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); $('td', row).eq(1).attr("align", "right"); $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); @@ -257,59 +234,14 @@ $('td', row).eq(12).attr('data-export', $('td', row).eq(12).text()); $('td', row).eq(13).attr('data-export', $('td', row).eq(13).text()); }, - 'data': trait_list, - 'columns': columnDefs, - "order": [[1, "asc" ]], - 'sDom': "iti", - "destroy": true, - "deferRender": true, - "bSortClasses": false, - {% if trait_count > 20 %} - "scrollY": "100vh", - "scroller": true, - "scrollCollapse": true, + {% if trait_count <= 20 %} + "scroller": false {% else %} - "iDisplayLength": -1, + "scroller": true {% endif %} - "initComplete": function (settings) { - //Add JQueryUI resizable functionality to each th in the ScrollHead table - $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ - handles: "e", - alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother - resize: function( event, ui ) { - width_change = ui.size.width - ui.originalSize.width; - }, - stop: function () { - saveColumnSettings(tableId, trait_table); - loadDataTable(); - } - }); - } - } - - if (!first_run){ - table_settings['autoWidth'] = false; - $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly - } - - let checked_rows = get_checked_rows(tableId); - trait_table = $('#' + tableId).DataTable(table_settings); - if (checked_rows.length > 0){ - recheck_rows(trait_table, checked_rows); - } - - if (first_run){ - {% if trait_list|length > 20 %} - $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); - {% endif %} - trait_table.draw(); - } } - $('#redraw').click(function() { - var table = $('#' + tableId).DataTable(); - table.colReorder.reset() - }); + create_table(tableId, traitsJson, columnDefs, tableSettings); }); diff --git a/wqflask/wqflask/templates/gsearch_pheno.html b/wqflask/wqflask/templates/gsearch_pheno.html index 7abdb222..0d18a0bf 100644 --- a/wqflask/wqflask/templates/gsearch_pheno.html +++ b/wqflask/wqflask/templates/gsearch_pheno.html @@ -56,6 +56,7 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/colResize/dataTables.colResize.js') }}"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script type='text/javascript'> var getParams = function(url) { @@ -70,22 +71,20 @@ </script> <script type='text/javascript'> - var trait_list = {{ trait_list|safe }}; + var traitsJson = {{ trait_list|safe }}; </script> <script type="text/javascript" charset="utf-8"> $(document).ready( function () { 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 - columnDefs = [ { 'data': null, 'orderDataType': "dom-checkbox", 'width': "10px", 'targets': 0, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<input type="checkbox" name="searchResult" class="trait_checkbox checkbox" value="' + data.hmac + '">' } }, @@ -117,7 +116,7 @@ 'width': "60px", 'targets': 4, 'orderDataType': "dom-inner-text", - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' } }, @@ -127,7 +126,7 @@ 'width': "500px", 'targets': 5, 'data': null, - 'render': function(data, type, row, meta) { + 'render': function(data) { try { return decodeURIComponent(escape(data.description)) } catch(err) { @@ -147,16 +146,7 @@ 'type': "natural", 'width': "300px", 'targets': 7, - 'data': null, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 6) { - author_string = author_list.slice(0, 6).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string - } + 'data': "authors_display" }, { 'title': "Year", @@ -165,7 +155,7 @@ 'orderDataType': "dom-inner-text", 'width': "25px", 'targets': 8, - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.pubmed_id != "N/A"){ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>' } else { @@ -199,30 +189,8 @@ } ] - loadDataTable(true); - - function loadDataTable(first_run=false){ - - if (!first_run){ - setUserColumnsDefWidths(tableId); - } - - table_settings = { - 'drawCallback': function( settings ) { - $('#' + tableId + ' tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - "createdRow": function ( row, data, index ) { + tableSettings = { + "createdRow": function ( row, data, index ) { $('td', row).eq(0).attr("style", "text-align: center; padding: 4px 10px 2px 10px;"); $('td', row).eq(1).attr("align", "right"); $('td', row).eq(5).attr('title', $('td', row).eq(5).text()); @@ -248,60 +216,15 @@ $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); $('td', row).eq(10).attr('data-export', $('td', row).eq(10).text()); }, - 'data': trait_list, - 'columns': columnDefs, - "order": [[1, "asc" ]], - 'sDom': "iti", - "destroy": true, - "deferRender": true, - "bSortClasses": false, - {% if trait_count > 20 %} - "scrollY": "100vh", - "scroller": true, - "scrollCollapse": true, + {% if trait_count <= 20 %} + "scroller": false {% else %} - "iDisplayLength": -1, + "scroller": true {% endif %} - "initComplete": function (settings) { - //Add JQueryUI resizable functionality to each th in the ScrollHead table - $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ - handles: "e", - alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother - resize: function( event, ui ) { - width_change = ui.size.width - ui.originalSize.width; - }, - stop: function () { - saveColumnSettings(tableId, trait_table); - loadDataTable(); - } - }); - } - } + } - if (!first_run){ - table_settings['autoWidth'] = false; - $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); // Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly - } - - let checked_rows = get_checked_rows(tableId); - trait_table = $('#' + tableId).DataTable(table_settings); - if (checked_rows.length > 0){ - recheck_rows(trait_table, checked_rows); - } - - if (first_run){ - {% if trait_list|length > 20 %} - $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); - {% endif %} - } - - trait_table.draw(); - } + create_table(tableId, traitsJson, columnDefs, tableSettings); - $('#redraw').click(function() { - var table = $('#' + tableId).DataTable(); - table.colReorder.reset() - }); }); </script> {% endblock %} diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 29e9002d..55d18cba 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -65,7 +65,7 @@ <input type="hidden" name="form_url" value="/run_mapping"> <div class="container" style="width: 1200px; float: left;"> - <div class="col-xs-4"> + <div class="col-xs-4" style="word-wrap: normal;"> <h2>Map Viewer: Whole Genome</h2><br> <b>Population:</b> {{ dataset.group.species|capitalize }} {{ dataset.group.name }}<br> <b>Database:</b> {{ dataset.fullname }}<br> @@ -258,63 +258,10 @@ <button class="btn btn-default export_mapping_results" >Download <span class="glyphicon glyphicon-download"></span></button> <br /> <br /> - <div id="table_container" style="width:{% if 'additive' in trimmed_markers[0] %}600{% else %}550{% endif %}px;"> - <table id="trait_table" class="table-hover table-striped cell-border dataTable no-footer"> - <thead> - <tr> - <th></th> - <th>Row</th> - <th>Marker</th> - {% if LRS_LOD == "-logP" %} - <th><div style="text-align: right;">–logP</div></th> - {% else %} - <th><div style="text-align: right;">{{ LRS_LOD }}</div></th> - {% endif %} - <th><div style="text-align: right;">Position ({% if plotScale == "physic" %}Mb{% else %}cM{% endif %})</div></th> - {% if 'additive' in trimmed_markers[0] %} - <th><div style="text-align: right;">Add Eff</div></th> - {% endif %} - {% if 'dominance' in trimmed_markers[0] and dataset.group.genetic_type != "riset" %} - <th><div style="text-align: right;">Dom Eff</div></th> - {% endif %} - </tr> - </thead> + <div id="trait_table_container" style="width:{% if 'additive' in trimmed_markers[0] %}600{% else %}550{% endif %}px;"> + <table class="table-hover table-striped cell-border no-footer" id='trait_table' style="float: left;"> <tbody> - {% for marker in trimmed_markers %} - <tr> - <td align="center" style="padding: 1px 0px 1px 0px;"> - <input type="checkbox" name="selectCheck" - class="checkbox trait_checkbox" - value="{{ data_hmac('{}:{}Geno'.format(marker.name, dataset.group.name)) }}"> - </td> - <td align="right">{{ loop.index }}</td> - <td>{% if geno_db_exists == "True" %}<a href="/show_trait?trait_id={{ marker.name }}&dataset={{ dataset.group.name }}Geno">{{ marker.name }}</a>{% else %}{{ marker.name }}{% endif %}</td> - {% if LRS_LOD == "LOD" or LRS_LOD == "-logP" %} - {% if 'lod_score' in marker %} - <td align="right">{{ '%0.2f' | format(marker.lod_score|float) }}</td> - {% else %} - <td align="right">{{ '%0.2f' | format(marker.lrs_value|float / 4.61) }}</td> - {% endif %} - {% else %} - {% if 'lod_score' in marker %} - <td align="right">{{ '%0.2f' | format(marker.lod_score|float * 4.61) }}</td> - {% else %} - <td align="right">{{ '%0.2f' | format(marker.lrs_value|float) }}</td> - {% endif %} - {% endif %} - <td align="right">{{ marker.display_pos }}</td> - {% if 'additive' in marker %} - {% if geno_db_exists == "True" %} - <td align="right"><a target"_blank" href="corr_scatter_plot?method=pearson&dataset_1={{ dataset.group.name }}Geno&dataset_2={{ dataset.name }}&trait_1={{ marker.name }}&trait_2={{ this_trait.name }}">{{ '%0.3f' | format(marker.additive|float) }}</a></td> - {% else %} - <td align="right">{{ '%0.3f' | format(marker.additive|float) }}</td> - {% endif %} - {% endif %} - {% if 'dominance' in marker and dataset.group.genetic_type != "riset" %} - <td align="right">{{ '%0.2f' | format(marker.dominance|float) }}</td> - {% endif %} - </tr> - {% endfor %} + <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td> </tbody> </table> </div> @@ -376,59 +323,143 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='purescript-genome-browser/js/purescript-genetics-browser.js') }}"></script> <script> - js_data = {{ js_data | safe }} + var js_data = {{ js_data | safe }}; + var markersJson = {{ trimmed_markers|safe }}; </script> <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> {% if mapping_method == "gemma" or mapping_method == "reaper" %} <script language="javascript" type="text/javascript" src="/static/new/javascript/init_genome_browser.js"></script> {% endif %} <script type="text/javascript" charset="utf-8"> $(document).ready( function () { - console.time("Creating table"); - {% if selectedChr == -1 %} - $('#trait_table').DataTable( { - "drawCallback": function( settings ) { - $('#trait_table tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } + tableId = "trait_table" + + columnDefs = [ + { + 'data': null, + 'width': "5px", + 'orderDataType': "dom-checkbox", + 'targets': 0, + 'render': function(data, type, row, meta) { + return '<input type="checkbox" name="selectCheck" class="checkbox trait_checkbox" value="'+ data.hmac + '">' + } + }, + { + 'title': "Row", + 'type': "natural", + 'width': "35px", + 'searchable': false, + 'orderable': false, + 'targets': 1, + 'render': function(data, type, row, meta) { + return meta.row + } + }, + { + 'title': "Marker", + 'type': "natural", + 'width': "20%", + 'targets': 2, + {% if geno_db_exists == "True" %} + 'data': null, + 'render': function(data, type, row, meta) { + return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset={{ dataset.group.name }}Geno">' + data.name + '</a>' + } + {% else %} + 'data': "name" + {% endif %} + }, + { + 'title': "<div style='text-align: right;'>{{ LRS_LOD }}</div>", + 'type': "natural", + 'width': "60px", + 'targets': 3, + 'orderSequence': [ "desc", "asc"], + 'data': null, + 'render': function(data, type, row, meta) { + {% if (LRS_LOD == "LOD") or (LRS_LOD == "-logP") %} + if ('lod_score' in data){ + return String(parseFloat(data.lod_score).toFixed(2)) + } else { + return String((parseFloat(data.lrs_value) / 4.61).toFixed(2)) + } + {% else %} + if ('lod_score' in data){ + return String((parseFloat(data.lod_score) * 4.61).toFixed(2)) + } else { + return String(parseFloat(data.lrs_value).toFixed(2)) + } + {% endif %} + } + }, + { + 'title': "<div style='text-align: right;'>Position ({% if plotScale == 'physic' %}Mb{% else %}cM{% endif %})</div>", + 'type': 'natural', + 'targets': 4, + 'data': "display_pos" + }, + {% if 'additive' in trimmed_markers[0] %} + { + 'title': "<div style='text-align: right;'>Add Eff</div>", + 'type': "natural", + 'targets': 5, + 'data': null, + 'render': function(data, type, row, meta) { + {% if geno_db_exists == "True" %} + return '<a target"_blank" href="corr_scatter_plot?method=pearson&dataset_1={{ dataset.group.name }}Geno&dataset_2={{ dataset.name }}&trait_1=' + data.name + '&trait_2={{ this_trait.name }}">' + String(parseFloat(data.additive).toFixed(3)) + '</a>' + {% else %} + return String(parseFloat(data.additive).toFixed(3)) + {% endif %} + } + }, + {% endif %} + {% if ('dominance' in trimmed_markers[0]) and (dataset.group.genetic_type != "riset") %} + { + 'title': "<div style='text-align: right;'>Add Eff</div>", + 'type': "natural", + 'targets': {% if ('additive' in trimmed_markers[0]) %}6{% else %}5{% endif %}, + 'data': null, + 'render': function(data, type, row, meta) { + return String(parseFloat(data.dominance).toFixed(2)) + } + } + {% endif %} + ] + + tableSettings = { + "createdRow": function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + $('td', row).eq(3).attr("align", "right"); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + $('td', row).eq(4).attr("align", "right"); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + {% if 'additive' in trimmed_markers[0] %} + $('td', row).eq(5).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + {% endif %} + {% if 'dominance' in trimmed_markers[0] %} + $('td', row).eq(6).attr("align", "right"); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + {% endif %} + }, + "language": { + "info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records", + }, + "order": [[1, "asc" ]], + "scrollY": "1000px", + "scroller": true + } + + create_table(tableId, markersJson, columnDefs, tableSettings) - {% if geno_db_exists == "True" %}change_buttons(check_node=1){% endif %} - }); - }, - "columns": [ - { "type": "natural", "width": "5%" }, - { "type": "natural", "width": "8%" }, - { "type": "natural", "width": "20%" }, - { "type": "natural" }, - { "type": "natural" }{% if 'additive' in qtlresults[0] %}, - { "type": "natural" }{% endif %}{% if 'dominance' in qtlresults[0] and dataset.group.genetic_type != "riset" %}, - { "type": "natural" }{% endif %} - ], - "columnDefs": [ { - "targets": 0, - "orderable": false - } ], - "language": { - "info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records", - }, - "order": [[1, "asc" ]], - "sDom": "itir", - "autoWidth": true, - "bSortClasses": 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( { "drawCallback": function( settings ) { diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 264b383d..3b01f4a6 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -136,7 +136,7 @@ {% endif %} </div> {% endif %} - <div id="table_container" style="width: {% if dataset.type == 'Geno' %}375px;{% else %}100%; min-width: 1400px;{% endif %}"> + <div id="trait_table_container" style="{% if dataset.type == 'Geno' %}width: 450px;{% else %} min-width: 800px;{% endif %}"> <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;"> <tbody> <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td> @@ -168,11 +168,11 @@ <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/partial_correlations.js"></script> - <script type='text/javascript'> - var trait_list = {{ trait_list|safe }}; + var traitsJson = {{ trait_list|safe }}; </script> <script type="text/javascript" charset="utf-8"> @@ -191,7 +191,7 @@ {% if results|count > 0 and not too_many_results %} 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 + var widthChange = 0; //ZS: For storing the change in width so overall table width can be adjusted by that amount columnDefs = [ { @@ -199,7 +199,7 @@ 'width': "5px", 'orderDataType': "dom-checkbox", 'targets': 0, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '" data-trait-info="' + data.trait_info_str + '">' } }, @@ -219,7 +219,7 @@ 'data': null, 'width': "{{ max_widths.display_name * 8 }}px", 'targets': 2, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<a target="_blank" href="/show_trait?trait_id=' + data.display_name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' } }, @@ -235,7 +235,7 @@ 'type': "natural", 'data': null, 'targets': 4, - 'render': function(data, type, row, meta) { + 'render': function(data) { try { return decodeURIComponent(escape(data.description)) } catch(err){ @@ -287,7 +287,7 @@ 'width': "{{ max_widths.display_name * 9 }}px", 'data': null, 'targets': 2, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' } }, @@ -301,7 +301,7 @@ {% endif %} 'data': null, 'targets': 3, - 'render': function(data, type, row, meta) { + 'render': function(data) { try { return decodeURIComponent(escape(data.description)) } catch(err){ @@ -325,17 +325,8 @@ {% else %} 'width': "500px", {% endif %} - 'data': null, - 'targets': 5, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 2) { - author_string = author_list.slice(0, 2).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string - } + 'data': "authors_display", + 'targets': 5 }, { 'title': "<div style='text-align: right;'>Year</div>", @@ -343,7 +334,7 @@ 'data': null, 'width': "50px", 'targets': 6, - 'render': function(data, type, row, meta) { + 'render': function(data) { if (data.pubmed_id != "N/A"){ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>' } else { @@ -381,7 +372,7 @@ 'width': "{{ max_widths.display_name * 9 }}px", 'data': null, 'targets': 2, - 'render': function(data, type, row, meta) { + 'render': function(data) { return '<a target="_blank" href="/show_trait?trait_id=' + data.display_name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' } }, @@ -394,155 +385,61 @@ }{% endif %} ]; - loadDataTable(true); - - function loadDataTable(first_run=false){ - - if (!first_run){ - setUserColumnsDefWidths(tableId); - } - - //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters - table_settings = { - 'drawCallback': function( settings ) { - $('#' + tableId + ' tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - 'createdRow': function ( row, data, index ) { - $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr('data-export', index+1); - $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); - {% if dataset.type == 'ProbeSet' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - if ($('td', row).eq(3).text().length > 20) { - $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); - $('td', row).eq(3).text($('td', row).eq(3).text() + '...') - } - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - if ($('td', row).eq(4).text().length > 500) { - $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 500)); - $('td', row).eq(4).text($('td', row).eq(4).text() + '...') - } - $('td', row).slice(5,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); - {% elif dataset.type == 'Publish' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - if ($('td', row).eq(3).text().length > 500) { - $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 500)); - $('td', row).eq(3).text($('td', row).eq(3).text() + '...') - } - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('align', 'right'); - $('td', row).slice(6,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); - {% elif dataset.type == 'Geno' %} - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - {% endif %} - }, - "data": trait_list, - "columns": columnDefs, - "order": [[1, "asc" ]], - "sDom": "iti", - "destroy": true, - "autoWidth": false, - "bSortClasses": false, - "scrollY": "1000px", - "scrollCollapse": true, - {% if trait_list|length > 10 %} - "scroller": true, - {% endif %} - "iDisplayLength": -1, - "initComplete": function (settings) { - //Add JQueryUI resizable functionality to each th in the ScrollHead table - $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ - handles: "e", - alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother - resize: function( event, ui ) { - width_change = ui.size.width - ui.originalSize.width; - }, - stop: function () { - saveColumnSettings(tableId, trait_table); - loadDataTable(); - } - }); + tableSettings = { + "createdRow": function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + {% if dataset.type == 'ProbeSet' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 20) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') } - } - - if (!first_run){ - $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly - - let checked_rows = get_checked_rows(tableId); - trait_table = $('#' + tableId).DataTable(table_settings); - if (checked_rows.length > 0){ - recheck_rows(trait_table, checked_rows); + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + if ($('td', row).eq(4).text().length > 500) { + $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 500)); + $('td', row).eq(4).text($('td', row).eq(4).text() + '...') } - } else { - trait_table = $('#' + tableId).DataTable(table_settings); - trait_table.draw(); - } - - if (first_run){ - {% if trait_list|length > 20 %} - $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); - {% else %} - $('#table_container').css("width", String($('#trait_table').width()) + "px"); + $('td', row).slice(5,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); + {% elif dataset.type == 'Publish' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 500) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 500)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') + } + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('align', 'right'); + $('td', row).slice(6,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); + {% elif dataset.type == 'Geno' %} + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); {% endif %} - } + }, + "order": [[1, "asc" ]], + {% if traits_json|length > 10 %} + "scrollY": "1000px", + "scroller": true + {% else %} + "scroller": false + {% endif %} } - trait_table.on( 'order.dt search.dt', function () { - trait_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { - cell.innerHTML = i+1; - } ); - } ).draw(); - - window.addEventListener('resize', function(){ - trait_table.columns.adjust(); - }); - - $('.toggle-vis').on( 'click', function (e) { - e.preventDefault(); - - // Get the column API object - var column = trait_table.column( $(this).attr('data-column') ); - - // Toggle the visibility - column.visible( ! column.visible() ); - - if (column.visible()){ - $(this).removeClass("active"); - } else { - $(this).addClass("active"); - } - } ); - - $('#redraw').click(function() { - var table = $('#' + tableId).DataTable(); - table.colReorder.reset() - }); + create_table(tableId, traitsJson, columnDefs, tableSettings) {% endif %} submit_special = function(url) { diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 460c7c62..0f93188b 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -131,19 +131,19 @@ $('.collapse').collapse() </script> - <script type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='js_alt/jstat.min.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script> - <script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script> - <script type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/jstat.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script> - <script type="text/javascript" src="/static/new/javascript/stats.js"></script> - <script type="text/javascript" src="/static/new/javascript/scatter-matrix.js"></script> - <script type="text/javascript" src="/static/new/javascript/plotly_probability_plot.js"></script> - <script type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/stats.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/scatter-matrix.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/plotly_probability_plot.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script> @@ -151,12 +151,13 @@ <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='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='nouislider/nouislider.js') }}"></script> - <script type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script> - <script type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script> - <script type="text/javascript" src="/static/new/javascript/show_trait.js"></script> - <script type="text/javascript" src="/static/new/javascript/validation.js"></script> - <script type="text/javascript" src="/static/new/javascript/get_covariates_from_collection.js"></script> - <script type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/show_trait.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/validation.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/javascript/get_covariates_from_collection.js"></script> <script type="text/javascript" charset="utf-8"> diff --git a/wqflask/wqflask/update_search_results.py b/wqflask/wqflask/update_search_results.py index 2e467dc8..f132e2c6 100644 --- a/wqflask/wqflask/update_search_results.py +++ b/wqflask/wqflask/update_search_results.py @@ -5,11 +5,6 @@ from base.data_set import create_dataset from base.trait import GeneralTrait from db import webqtlDatabaseFunction -from utility.benchmark import Bench - -from utility.logger import getLogger -logger = getLogger(__name__) - class GSearch: @@ -46,19 +41,15 @@ class GSearch: ORDER BY species_name, inbredset_name, tissue_name, probesetfreeze_name, probeset_name LIMIT 6000 """ % (self.terms) - with Bench("Running query"): - logger.sql(sql) - re = g.db.execute(sql).fetchall() + re = g.db.execute(sql).fetchall() self.trait_list = [] - with Bench("Creating trait objects"): - for line in re: - dataset = create_dataset( - line[3], "ProbeSet", get_samplelist=False) - trait_id = line[4] - # with Bench("Building trait object"): - this_trait = GeneralTrait( - dataset=dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) - self.trait_list.append(this_trait) + for line in re: + dataset = create_dataset( + line[3], "ProbeSet", get_samplelist=False) + trait_id = line[4] + this_trait = GeneralTrait( + dataset=dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) + self.trait_list.append(this_trait) elif self.type == "phenotype": sql = """ @@ -92,16 +83,14 @@ class GSearch: ORDER BY Species.`Name`, InbredSet.`Name`, PublishXRef.`Id` LIMIT 6000 """ % (self.terms, self.terms, self.terms, self.terms, self.terms, self.terms, self.terms, self.terms, self.terms, self.terms) - logger.sql(sql) re = g.db.execute(sql).fetchall() self.trait_list = [] - with Bench("Creating trait objects"): - for line in re: - dataset = create_dataset(line[2], "Publish") - trait_id = line[3] - this_trait = GeneralTrait( - dataset=dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) - self.trait_list.append(this_trait) + for line in re: + dataset = create_dataset(line[2], "Publish") + trait_id = line[3] + this_trait = GeneralTrait( + dataset=dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) + self.trait_list.append(this_trait) self.results = self.convert_to_json() diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index 45a12f77..ae61edb0 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -2,7 +2,6 @@ import os import hashlib import datetime import time -import logging import uuid import hmac import base64 @@ -21,9 +20,6 @@ from utility import hmac from utility.redis_tools import is_redis_available, get_redis_conn, get_user_id, get_user_by_unique_column, set_user_attribute, save_user, save_verification_code, check_verification_code, get_user_collections, save_collections Redis = get_redis_conn() -from utility.logger import getLogger -logger = getLogger(__name__) - from smtplib import SMTP from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD, LOG_SQL_ALCHEMY, GN2_BRANCH_URL @@ -129,7 +125,6 @@ def send_email(toaddr, msg, fromaddr="no-reply@genenetwork.org"): server.login(SMTP_USERNAME, SMTP_PASSWORD) server.sendmail(fromaddr, toaddr, msg) server.quit() - logger.info("Successfully sent email to " + toaddr) def send_verification_email(user_details, template_name="email/user_verification.txt", key_prefix="verification_code", subject="GeneNetwork e-mail verification"): @@ -346,7 +341,6 @@ def get_github_user_details(access_token): @app.route("/n/logout") def logout(): - logger.debug("Logging out...") UserSession().delete_session() flash("You are now logged out. We hope you come back soon!") response = make_response(redirect(url_for('index_page'))) @@ -404,7 +398,6 @@ def forgot_password_submit(): email_address = params['email_address'] next_page = None if email_address != "": - logger.debug("Wants to send password E-mail to ", email_address) user_details = get_user_by_unique_column( "email_address", email_address) if user_details: @@ -425,8 +418,6 @@ def forgot_password_submit(): @app.route("/n/password_reset", methods=['GET']) def password_reset(): """Entry point after user clicks link in E-mail""" - logger.debug("in password_reset request.url is:", request.url) - verification_code = request.args.get('code') hmac = request.args.get('hm') @@ -446,8 +437,6 @@ def password_reset(): @app.route("/n/password_reset_step2", methods=('POST',)) def password_reset_step2(): """Handle confirmation E-mail for password reset""" - logger.debug("in password_reset request.url is:", request.url) - errors = [] user_email = request.form['user_encode'] user_id = get_user_id("email_address", user_email) @@ -515,7 +504,6 @@ def register(): params = params.to_dict(flat=True) if params: - logger.debug("Attempting to register the user...") errors = register_user(params) if len(errors) == 0: diff --git a/wqflask/wqflask/user_session.py b/wqflask/wqflask/user_session.py index 00b268a7..1ed5b802 100644 --- a/wqflask/wqflask/user_session.py +++ b/wqflask/wqflask/user_session.py @@ -13,8 +13,6 @@ from utility import hmac from utility.redis_tools import get_redis_conn, get_user_id, get_user_by_unique_column, set_user_attribute, get_user_collections, save_collections Redis = get_redis_conn() -from utility.logger import getLogger -logger = getLogger(__name__) THREE_DAYS = 60 * 60 * 24 * 3 THIRTY_DAYS = 60 * 60 * 24 * 30 @@ -54,7 +52,6 @@ def create_signed_cookie(): the_uuid = str(uuid.uuid4()) signature = hmac.hmac_creation(the_uuid) uuid_signed = the_uuid + ":" + signature - logger.debug("uuid_signed:", uuid_signed) return the_uuid, uuid_signed diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index e054cd49..acd65587 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -95,37 +95,34 @@ from utility.redis_tools import get_redis_conn from base.webqtlConfig import GENERATED_IMAGE_DIR, DEFAULT_PRIVILEGES -from utility.benchmark import Bench from pprint import pformat as pf -import utility.logger - Redis = get_redis_conn() -logger = utility.logger.getLogger(__name__) - @app.before_request def connect_db(): db = getattr(g, '_database', None) if request.endpoint not in ("static", "js") and db is None: - logger.debug( - f"Creating a database connection\n" - f"\t\tfor request: {request.endpoint}") - g.db = g._database = sqlalchemy.create_engine( - SQL_URI, encoding="latin1") + try: + g.db = sqlalchemy.create_engine( + SQL_URI, encoding="latin1") + except Exception: # Capture everything + app.logger.error(f"DATABASE: Error creating connection for: {request.endpoint}") @app.teardown_appcontext def shutdown_session(exception=None): db = getattr(g, '_database', None) if db is not None: - logger.debug(f"Removing the session") - g.db.dispose() - g.db = None - logger.debug(f"g.db: {g.db}\n\tg._database: {g._database}") + try: + g.db.dispose() + except Exception: # Capture Everything + app.logger.error(f"DATABASE: Error disposing: {g.db=}") + finally: # Reset regardless of what happens + g.db = None @app.errorhandler(Exception) @@ -219,12 +216,11 @@ def twitter(filename): def search_page(): result = None if USE_REDIS: - with Bench("Trying Redis cache"): - key = "search_results:v1:" + \ - json.dumps(request.args, sort_keys=True) - result = Redis.get(key) - if result: - result = pickle.loads(result) + key = "search_results:v1:" + \ + json.dumps(request.args, sort_keys=True) + result = Redis.get(key) + if result: + result = pickle.loads(result) the_search = SearchResultPage(request.args) result = the_search.__dict__ valid_search = result['search_term_exists'] @@ -531,12 +527,10 @@ def heatmap_page(): version = "v5" key = "heatmap:{}:".format( version) + json.dumps(start_vars, sort_keys=True) - with Bench("Loading cache"): - result = Redis.get(key) + result = Redis.get(key) if result: - with Bench("Loading results"): - result = pickle.loads(result) + result = pickle.loads(result) else: template_vars = heatmap.Heatmap(request.form, temp_uuid) @@ -549,9 +543,7 @@ def heatmap_page(): pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL) Redis.set(key, pickled_result) Redis.expire(key, 60 * 60) - - with Bench("Rendering template"): - rendered_template = render_template("heatmap.html", **result) + rendered_template = render_template("heatmap.html", **result) else: rendered_template = render_template( @@ -764,40 +756,36 @@ def mapping_results_page(): version = "v3" key = "mapping_results:{}:".format( version) + json.dumps(start_vars, sort_keys=True) - with Bench("Loading cache"): - result = None # Just for testing + result = None # Just for testing if result: - with Bench("Loading results"): - result = pickle.loads(result) + result = pickle.loads(result) else: - with Bench("Total time in RunMapping"): - try: - template_vars = run_mapping.RunMapping(start_vars, temp_uuid) - if template_vars.no_results: - rendered_template = render_template("mapping_error.html") - return rendered_template - except: + try: + template_vars = run_mapping.RunMapping(start_vars, temp_uuid) + if template_vars.no_results: rendered_template = render_template("mapping_error.html") return rendered_template + except: + rendered_template = render_template("mapping_error.html") + return rendered_template - if not template_vars.pair_scan: - template_vars.js_data = json.dumps(template_vars.js_data, - default=json_default_handler, - indent=" ") + if not template_vars.pair_scan: + template_vars.js_data = json.dumps(template_vars.js_data, + default=json_default_handler, + indent=" ") - result = template_vars.__dict__ + result = template_vars.__dict__ - if result['pair_scan']: - with Bench("Rendering template"): - rendered_template = render_template( - "pair_scan_results.html", **result) - else: - gn1_template_vars = display_mapping_results.DisplayMappingResults( - result).__dict__ + if result['pair_scan']: + rendered_template = render_template( + "pair_scan_results.html", **result) + else: + gn1_template_vars = display_mapping_results.DisplayMappingResults( + result).__dict__ - rendered_template = render_template( - "mapping_results.html", **gn1_template_vars) + rendered_template = render_template( + "mapping_results.html", **gn1_template_vars) return rendered_template |