diff options
Diffstat (limited to 'wqflask')
18 files changed, 1157 insertions, 1099 deletions
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index e0ef559c..2f1549ae 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -150,10 +150,12 @@ Publish or ProbeSet. E.g. "geno": "Geno", } + group_name = name if t in ['pheno', 'other_pheno']: - name = name.replace("Publish", "") + group_name = name.replace("Publish", "") - if bool(len(g.db.execute(sql_query_mapping[t].format(name)).fetchone())): + results = g.db.execute(sql_query_mapping[t].format(group_name)).fetchone() + if results: self.datasets[name] = dataset_name_mapping[t] self.redis_instance.set("dataset_structure", json.dumps(self.datasets)) return True diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 8f8b5b70..7ebbc4bb 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -1,4 +1,10 @@ from __future__ import absolute_import, division, print_function +from utility.logger import getLogger +from flask import Flask, g, request, url_for, redirect, make_response, render_template +from pprint import pformat as pf +from MySQLdb import escape_string as escape +import simplejson as json +from wqflask import app import os import string @@ -16,22 +22,19 @@ from utility import webqtlUtil from utility import hmac from utility.authentication_tools import check_resource_availability from utility.tools import GN2_BASE_URL, GN_VERSION -from utility.redis_tools import get_redis_conn, get_resource_id, get_resource_info -Redis = get_redis_conn() +from utility.redis_tools import get_redis_conn +from utility.redis_tools import get_resource_id +from utility.redis_tools import get_resource_info -from wqflask import app +Redis = get_redis_conn() -import simplejson as json -from MySQLdb import escape_string as escape -from pprint import pformat as pf -from flask import Flask, g, request, url_for, redirect, make_response, render_template +logger = getLogger(__name__) -from utility.logger import getLogger -logger = getLogger(__name__ ) def create_trait(**kw): - assert bool(kw.get('dataset')) != bool(kw.get('dataset_name')), "Needs dataset ob. or name"; + assert bool(kw.get('dataset')) != bool( + kw.get('dataset_name')), "Needs dataset ob. or name" permitted = True if kw.get('name'): @@ -43,18 +46,21 @@ def create_trait(**kw): if kw.get('dataset_name') != "Temp": if dataset.type == 'Publish': - permissions = check_resource_availability(dataset, kw.get('name')) + permissions = check_resource_availability( + dataset, kw.get('name')) else: permissions = check_resource_availability(dataset) if "view" in permissions['data']: the_trait = GeneralTrait(**kw) if the_trait.dataset.type != "Temp": - the_trait = retrieve_trait_info(the_trait, the_trait.dataset, get_qtl_info=kw.get('get_qtl_info')) + the_trait = retrieve_trait_info( + the_trait, the_trait.dataset, get_qtl_info=kw.get('get_qtl_info')) return the_trait else: return None + class GeneralTrait(object): """ Trait class defines a trait in webqtl, can be either Microarray, @@ -64,12 +70,15 @@ class GeneralTrait(object): def __init__(self, get_qtl_info=False, get_sample_info=True, **kw): # xor assertion - assert bool(kw.get('dataset')) != bool(kw.get('dataset_name')), "Needs dataset ob. or name"; - self.name = kw.get('name') # Trait ID, ProbeSet ID, Published ID, etc. + assert bool(kw.get('dataset')) != bool( + kw.get('dataset_name')), "Needs dataset ob. or name" + # Trait ID, ProbeSet ID, Published ID, etc. + self.name = kw.get('name') if kw.get('dataset_name'): if kw.get('dataset_name') == "Temp": temp_group = self.name.split("_")[2] - self.dataset = create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = temp_group) + self.dataset = create_dataset( + dataset_name="Temp", dataset_type="Temp", group_name=temp_group) else: self.dataset = create_dataset(kw.get('dataset_name')) else: @@ -77,7 +86,8 @@ class GeneralTrait(object): self.cellid = kw.get('cellid') self.identification = kw.get('identification', 'un-named trait') self.haveinfo = kw.get('haveinfo', False) - self.sequence = kw.get('sequence') # Blat sequence, available for ProbeSet + # Blat sequence, available for ProbeSet + self.sequence = kw.get('sequence') self.data = kw.get('data', {}) self.view = True @@ -125,11 +135,11 @@ class GeneralTrait(object): vals.append(sample_data.value) the_vars.append(sample_data.variance) sample_aliases.append(sample_data.name2) - return samples, vals, the_vars, sample_aliases + return samples, vals, the_vars, sample_aliases @property def description_fmt(self): - '''Return a text formated description''' + """Return a text formated description""" if self.dataset.type == 'ProbeSet': if self.description: formatted = self.description @@ -149,7 +159,7 @@ class GeneralTrait(object): @property def alias_fmt(self): - '''Return a text formatted alias''' + """Return a text formatted alias""" alias = 'Not available' if getattr(self, "alias", None): @@ -160,16 +170,20 @@ class GeneralTrait(object): @property def wikidata_alias_fmt(self): - '''Return a text formatted alias''' + """Return a text formatted alias""" alias = 'Not available' if self.symbol: - human_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.upper()) - mouse_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.capitalize()) - other_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.lower()) + human_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.upper()) + mouse_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.capitalize()) + other_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.lower()) if human_response and mouse_response and other_response: - alias_list = json.loads(human_response.content) + json.loads(mouse_response.content) + json.loads(other_response.content) + alias_list = json.loads(human_response.content) + json.loads( + mouse_response.content) + json.loads(other_response.content) filtered_aliases = [] seen = set() @@ -183,31 +197,31 @@ class GeneralTrait(object): return alias - @property def location_fmt(self): - '''Return a text formatted location + """Return a text formatted location While we're at it we set self.location in case we need it later (do we?) - ''' + """ if self.chr and self.mb: - self.location = 'Chr %s @ %s Mb' % (self.chr,self.mb) + self.location = 'Chr %s @ %s Mb' % (self.chr, self.mb) elif self.chr: self.location = 'Chr %s @ Unknown position' % (self.chr) else: self.location = 'Not available' fmt = self.location - ##XZ: deal with direction + # XZ: deal with direction if self.strand_probe == '+': fmt += (' on the plus strand ') elif self.strand_probe == '-': fmt += (' on the minus strand ') return fmt - + + def retrieve_sample_data(trait, dataset, samplelist=None): if samplelist == None: samplelist = [] @@ -225,16 +239,19 @@ def retrieve_sample_data(trait, dataset, samplelist=None): all_samples_ordered = dataset.group.all_samples_ordered() for i, item in enumerate(results): try: - trait.data[all_samples_ordered[i]] = webqtlCaseData(all_samples_ordered[i], float(item)) + trait.data[all_samples_ordered[i]] = webqtlCaseData( + all_samples_ordered[i], float(item)) except: pass else: for item in results: name, value, variance, num_cases, name2 = item if not samplelist or (samplelist and name in samplelist): - trait.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) + # name, value, variance, num_cases) + trait.data[name] = webqtlCaseData(*item) return trait + @app.route("/trait/get_sample_data") def get_sample_data(): params = request.args @@ -250,7 +267,8 @@ def get_sample_data(): trait_dict['group'] = trait_ob.dataset.group.name trait_dict['tissue'] = trait_ob.dataset.tissue trait_dict['species'] = trait_ob.dataset.group.species - trait_dict['url'] = url_for('show_trait_page', trait_id = trait, dataset = dataset) + trait_dict['url'] = url_for( + 'show_trait_page', trait_id=trait, dataset=dataset) trait_dict['description'] = trait_ob.description_display if trait_ob.dataset.type == "ProbeSet": trait_dict['symbol'] = trait_ob.symbol @@ -260,22 +278,24 @@ def get_sample_data(): trait_dict['pubmed_link'] = trait_ob.pubmed_link trait_dict['pubmed_text'] = trait_ob.pubmed_text - return json.dumps([trait_dict, {key: value.value for key, value in trait_ob.data.iteritems() }]) + return json.dumps([trait_dict, {key: value.value for key, value in trait_ob.data.iteritems()}]) else: return None - + + def jsonable(trait): """Return a dict suitable for using as json Actual turning into json doesn't happen here though""" - dataset = create_dataset(dataset_name = trait.dataset.name, dataset_type = trait.dataset.type, group_name = trait.dataset.group.name) - + dataset = create_dataset(dataset_name=trait.dataset.name, + dataset_type=trait.dataset.type, group_name=trait.dataset.group.name) + if dataset.type == "ProbeSet": return dict(name=trait.name, symbol=trait.symbol, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, mean=trait.mean, location=trait.location_repr, @@ -287,7 +307,7 @@ def jsonable(trait): if trait.pubmed_id: return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, abbreviation=trait.abbreviation, authors=trait.authors, @@ -300,7 +320,7 @@ def jsonable(trait): else: return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, abbreviation=trait.abbreviation, authors=trait.authors, @@ -312,19 +332,20 @@ def jsonable(trait): elif dataset.type == "Geno": return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, location=trait.location_repr ) else: return dict() + def jsonable_table_row(trait, dataset_name, index): """Return a list suitable for json and intended to be displayed in a table Actual turning into json doesn't happen here though""" dataset = create_dataset(dataset_name) - + if dataset.type == "ProbeSet": if trait.mean == "": mean = "N/A" @@ -336,11 +357,13 @@ def jsonable_table_row(trait, dataset_name, index): additive = "%.3f" % round(float(trait.additive), 2) return ['<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + hmac.data_hmac('{}:{}'.format(str(trait.name), dataset.name)) + '">', index, - '<a href="/show_trait?trait_id='+str(trait.name)+'&dataset='+dataset.name+'">'+str(trait.name)+'</a>', + '<a href="/show_trait?trait_id=' + + str(trait.name)+'&dataset='+dataset.name + + '">'+str(trait.name)+'</a>', trait.symbol, trait.description_display, trait.location_repr, - mean, + mean, trait.LRS_score_repr, trait.LRS_location_repr, additive] @@ -352,7 +375,9 @@ def jsonable_table_row(trait, dataset_name, index): if trait.pubmed_id: return ['<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + hmac.data_hmac('{}:{}'.format(str(trait.name), dataset.name)) + '">', index, - '<a href="/show_trait?trait_id='+str(trait.name)+'&dataset='+dataset.name+'">'+str(trait.name)+'</a>', + '<a href="/show_trait?trait_id=' + + str(trait.name)+'&dataset='+dataset.name + + '">'+str(trait.name)+'</a>', trait.description_display, trait.authors, '<a href="' + trait.pubmed_link + '">' + trait.pubmed_text + '</href>', @@ -362,7 +387,9 @@ def jsonable_table_row(trait, dataset_name, index): else: return ['<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + hmac.data_hmac('{}:{}'.format(str(trait.name), dataset.name)) + '">', index, - '<a href="/show_trait?trait_id='+str(trait.name)+'&dataset='+dataset.name+'">'+str(trait.name)+'</a>', + '<a href="/show_trait?trait_id=' + + str(trait.name)+'&dataset='+dataset.name + + '">'+str(trait.name)+'</a>', trait.description_display, trait.authors, trait.pubmed_text, @@ -372,7 +399,9 @@ def jsonable_table_row(trait, dataset_name, index): elif dataset.type == "Geno": return ['<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + hmac.data_hmac('{}:{}'.format(str(trait.name), dataset.name)) + '">', index, - '<a href="/show_trait?trait_id='+str(trait.name)+'&dataset='+dataset.name+'">'+str(trait.name)+'</a>', + '<a href="/show_trait?trait_id=' + + str(trait.name)+'&dataset='+dataset.name + + '">'+str(trait.name)+'</a>', trait.location_repr] else: return dict() @@ -383,14 +412,16 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): resource_id = get_resource_id(dataset, trait.name) if dataset.type == 'Publish': - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format( + resource_id, g.user_session.user_id) else: - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format( + resource_id, g.user_session.user_id, trait.name) try: response = requests.get(the_url).content trait_info = json.loads(response) - except: #ZS: I'm assuming the trait is viewable if the try fails for some reason; it should never reach this point unless the user has privileges, since that's dealt with in create_trait + except: # ZS: I'm assuming the trait is viewable if the try fails for some reason; it should never reach this point unless the user has privileges, since that's dealt with in create_trait if dataset.type == 'Publish': query = """ SELECT @@ -419,8 +450,8 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): logger.sql(query) trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name - #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + # XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name + # XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif dataset.type == 'ProbeSet': display_fields_string = ', ProbeSet.'.join(dataset.display_fields) display_fields_string = 'ProbeSet.' + display_fields_string @@ -433,14 +464,15 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' """ % (escape(display_fields_string), - escape(dataset.name), - escape(str(trait.name))) + escape(dataset.name), + escape(str(trait.name))) logger.sql(query) trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name + # XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif dataset.type == 'Geno': - display_fields_string = string.join(dataset.display_fields,',Geno.') + display_fields_string = string.join( + dataset.display_fields, ',Geno.') display_fields_string = 'Geno.' + display_fields_string query = """ SELECT %s @@ -451,21 +483,21 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): GenoFreeze.Name = '%s' AND Geno.Name = '%s' """ % (escape(display_fields_string), - escape(dataset.name), - escape(trait.name)) + escape(dataset.name), + escape(trait.name)) logger.sql(query) trait_info = g.db.execute(query).fetchone() - else: #Temp type + else: # Temp type query = """SELECT %s FROM %s WHERE Name = %s""" logger.sql(query) trait_info = g.db.execute(query, - (string.join(dataset.display_fields,','), - dataset.type, trait.name)).fetchone() + (string.join(dataset.display_fields, ','), + dataset.type, trait.name)).fetchone() if trait_info: trait.haveinfo = True for i, field in enumerate(dataset.display_fields): - holder = trait_info[i] + holder = trait_info[i] setattr(trait, field, holder) if dataset.type == 'Publish': @@ -478,9 +510,9 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): description = trait.post_publication_description - #If the dataset is confidential and the user has access to confidential - #phenotype traits, then display the pre-publication description instead - #of the post-publication description + # If the dataset is confidential and the user has access to confidential + # phenotype traits, then display the pre-publication description instead + # of the post-publication description if trait.confidential: trait.abbreviation = trait.pre_publication_abbreviation trait.description_display = trait.pre_publication_description @@ -491,9 +523,12 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): else: trait.description_display = "" - trait.abbreviation = unicode(str(trait.abbreviation).strip(codecs.BOM_UTF8), 'utf-8', errors="replace") - trait.description_display = unicode(str(trait.description_display).strip(codecs.BOM_UTF8), 'utf-8', errors="replace") - trait.authors = unicode(str(trait.authors).strip(codecs.BOM_UTF8), 'utf-8', errors="replace") + trait.abbreviation = unicode(str(trait.abbreviation).strip( + codecs.BOM_UTF8), 'utf-8', errors="replace") + trait.description_display = unicode(str(trait.description_display).strip( + codecs.BOM_UTF8), 'utf-8', errors="replace") + trait.authors = unicode(str(trait.authors).strip( + codecs.BOM_UTF8), 'utf-8', errors="replace") if not trait.year.isdigit(): trait.pubmed_text = "N/A" @@ -504,8 +539,10 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % trait.pubmed_id if dataset.type == 'ProbeSet' and dataset.group: - description_string = unicode(str(trait.description).strip(codecs.BOM_UTF8), 'utf-8') - target_string = unicode(str(trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8') + description_string = unicode( + str(trait.description).strip(codecs.BOM_UTF8), 'utf-8') + target_string = unicode( + str(trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8') if str(description_string or "") != "" and description_string != 'None': description_display = description_string @@ -514,7 +551,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if (str(description_display or "") != "" and description_display != 'N/A' and - str(target_string or "") != "" and target_string != 'None'): + str(target_string or "") != "" and target_string != 'None'): description_display = description_display + '; ' + target_string.strip() # Save it for the jinja2 template @@ -522,15 +559,17 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.location_repr = 'N/A' if trait.chr and trait.mb: - trait.location_repr = 'Chr%s: %.6f' % (trait.chr, float(trait.mb)) + trait.location_repr = 'Chr%s: %.6f' % ( + trait.chr, float(trait.mb)) elif dataset.type == "Geno": trait.location_repr = 'N/A' if trait.chr and trait.mb: - trait.location_repr = 'Chr%s: %.6f' % (trait.chr, float(trait.mb)) + trait.location_repr = 'Chr%s: %.6f' % ( + trait.chr, float(trait.mb)) if get_qtl_info: - #LRS and its location + # LRS and its location trait.LRS_score_repr = "N/A" trait.LRS_location_repr = "N/A" trait.locus = trait.locus_chr = trait.locus_mb = trait.lrs = trait.pvalue = trait.additive = "" @@ -601,10 +640,11 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): else: trait.locus = trait.lrs = trait.additive = "" if (dataset.type == 'Publish' or dataset.type == "ProbeSet") and str(trait.locus_chr or "") != "" and str(trait.locus_mb or "") != "": - trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (trait.locus_chr, float(trait.locus_mb)) + trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % ( + trait.locus_chr, float(trait.locus_mb)) if str(trait.lrs or "") != "": trait.LRS_score_repr = LRS_score_repr = '%3.1f' % trait.lrs else: - raise KeyError, `trait.name`+' information is not found in the database.' - + raise KeyError, `trait.name`+ ' information is not found in the database.' + return trait diff --git a/wqflask/base/webqtlCaseData.py b/wqflask/base/webqtlCaseData.py index 2844cedd..3cf2d80d 100644 --- a/wqflask/base/webqtlCaseData.py +++ b/wqflask/base/webqtlCaseData.py @@ -41,6 +41,8 @@ class webqtlCaseData: self.this_id = None # Set a sane default (can't be just "id" cause that's a reserved word) self.outlier = None # Not set to True/False until later + self.first_attr_col = self.get_first_attr_col() + def __repr__(self): case_data_string = "<webqtlCaseData> " if self.value is not None: @@ -79,3 +81,12 @@ class webqtlCaseData: if self.num_cases is not None: return "%s" % self.num_cases return "x" + + def get_first_attr_col(self): + col_num = 4 + if self.variance is not None: + col_num += 2 + if self.num_cases is not None: + col_num += 1 + + return col_num
\ No newline at end of file diff --git a/wqflask/tests/wqflask/test_collect.py b/wqflask/tests/wqflask/test_collect.py new file mode 100644 index 00000000..6b8d7931 --- /dev/null +++ b/wqflask/tests/wqflask/test_collect.py @@ -0,0 +1,57 @@ +"""Test cases for some methods in collect.py""" + +import unittest +import mock + +from flask import Flask +from wqflask.collect import process_traits + +app = Flask(__name__) + + +class MockSession: + """Helper class for mocking wqflask.collect.g.user_session.logged_in""" + def __init__(self, is_logged_in=False): + self.is_logged_in = is_logged_in + + @property + def logged_in(self): + return self.is_logged_in + + +class MockFlaskG: + """Helper class for mocking wqflask.collect.g.user_session""" + def __init__(self, is_logged_in=False): + self.is_logged_in = is_logged_in + + @property + def user_session(self): + if self.is_logged_in: + return MockSession(is_logged_in=True) + return MockSession() + + +class TestCollect(unittest.TestCase): + + def setUp(self): + self.app_context = app.app_context() + self.app_context.push() + + def tearDown(self): + self.app_context.pop() + + @mock.patch("wqflask.collect.g", MockFlaskG()) + def test_process_traits_when_user_is_logged_out(self): + """ + Test that the correct traits are returned when the user is logged + out + """ + self.assertEqual(process_traits( + b'1452452_at:HC_M2_0606_P:163d04f7db7c9e110de6,' + b'1452447_at:HC_M2_0606_P:eeece8fceb67072debea,' + b'1451401_a_at:HC_M2_0606_P:a043d23b3b3906d8318e,' + b'1429252_at:HC_M2_0606_P:6fa378b349bc9180e8f5'), + set(['1429252_at:HC_M2_0606_P', + '1451401_a_at:HC_M2_0606_P', + '1452447_at:HC_M2_0606_P', + '1452452_at:HC_M2_0606_P'])) diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 42a09fed..4c558bfe 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -1,41 +1,30 @@ from __future__ import print_function, division, absolute_import - -import os -import hashlib import datetime -import time - -import uuid -import hashlib -import base64 - -import urlparse - import simplejson as json -from flask import (Flask, g, render_template, url_for, request, make_response, - redirect, flash, jsonify) +from flask import g +from flask import render_template +from flask import url_for +from flask import request +from flask import redirect +from flask import flash from wqflask import app - -from pprint import pformat as pf - -from wqflask.database import db_session - -from wqflask import model - -from utility import Bunch, Struct, hmac +from utility import hmac from utility.formatting import numify from utility.redis_tools import get_redis_conn -Redis = get_redis_conn() -from base.trait import create_trait, retrieve_trait_info, jsonable +from base.trait import create_trait +from base.trait import retrieve_trait_info +from base.trait import jsonable from base.data_set import create_dataset -import logging from utility.logger import getLogger + logger = getLogger(__name__) +Redis = get_redis_conn() + def process_traits(unprocessed_traits): if isinstance(unprocessed_traits, basestring): diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index ad78ebcc..356db7bc 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -1,21 +1,20 @@ from __future__ import absolute_import, print_function, division -from flask import Flask, g - -from base import webqtlCaseData -from utility import webqtlUtil, Plot, Bunch -from base.trait import GeneralTrait +import itertools import numpy as np -from scipy import stats +from flask import Flask, g from pprint import pformat as pf +from scipy import stats -import simplejson as json - -import itertools +from base import webqtlCaseData +from base.trait import GeneralTrait +from utility import logger +from utility import webqtlUtil +from utility import Plot +from utility import Bunch -import utility.logger -logger = utility.logger.getLogger(__name__ ) +logger = logger.getLogger(__name__ ) class SampleList(object): def __init__(self, @@ -35,25 +34,22 @@ class SampleList(object): self.get_attributes() - #self.sample_qnorm = get_transform_vals(self.dataset, this_trait) - if self.this_trait and self.dataset: self.get_extra_attribute_values() for counter, sample_name in enumerate(sample_names, 1): sample_name = sample_name.replace("_2nd_", "") - if type(self.this_trait) is list: #ZS: self.this_trait will be a list if it is a Temp trait + if type(self.this_trait) is list: # ZS: self.this_trait will be a list if it is a Temp trait if counter <= len(self.this_trait) and str(self.this_trait[counter-1]).upper() != 'X': sample = webqtlCaseData.webqtlCaseData(name=sample_name, value=float(self.this_trait[counter-1])) else: sample = webqtlCaseData.webqtlCaseData(name=sample_name) else: - #ZS - If there's no value for the sample/strain, create the sample object (so samples with no value are still displayed in the table) + # ZS - If there's no value for the sample/strain, create the sample object (so samples with no value are still displayed in the table) try: sample = self.this_trait.data[sample_name] except KeyError: - #logger.debug("No sample %s, let's create it now" % sample_name) sample = webqtlCaseData.webqtlCaseData(name=sample_name) sample.extra_info = {} @@ -63,15 +59,13 @@ class SampleList(object): sample.this_id = str(counter) - #### For extra attribute columns; currently only used by several datasets - Zach + # ZS: For extra attribute columns; currently only used by several datasets if self.sample_attribute_values: sample.extra_attributes = self.sample_attribute_values.get(sample_name, {}) - #logger.debug("sample.extra_attributes is", pf(sample.extra_attributes)) self.sample_list.append(sample) - #logger.debug("attribute vals are", pf(self.sample_attribute_values)) - + self.se_exists = any(sample.variance for sample in self.sample_list) self.do_outliers() def __repr__(self): @@ -104,7 +98,6 @@ class SampleList(object): self.attributes = {} for attr, values in itertools.groupby(results.fetchall(), lambda row: (row.Id, row.Name)): key, name = attr - #logger.debug("radish: %s - %s" % (key, name)) self.attributes[key] = Bunch() self.attributes[key].name = name self.attributes[key].distinct_values = [item.Value for item in values] @@ -141,8 +134,8 @@ class SampleList(object): for item in items: attribute_value = item.Value - #ZS: If it's an int, turn it into one for sorting - #(for example, 101 would be lower than 80 if they're strings instead of ints) + # ZS: If it's an int, turn it into one for sorting + # (for example, 101 would be lower than 80 if they're strings instead of ints) try: attribute_value = int(attribute_value) except ValueError: @@ -151,53 +144,6 @@ class SampleList(object): attribute_values[self.attributes[item.Id].name] = attribute_value self.sample_attribute_values[sample_name] = attribute_values - def se_exists(self): - """Returns true if SE values exist for any samples, otherwise false""" - - return any(sample.variance for sample in self.sample_list) - -# def get_transform_vals(dataset, trait): -# es = get_elasticsearch_connection(for_user=False) - -# logger.info("DATASET NAME:", dataset.name) - -# query = '{"bool": {"must": [{"match": {"name": "%s"}}, {"match": {"dataset": "%s"}}]}}' % (trait.name, dataset.name) - -# es_body = { -# "query": { -# "bool": { -# "must": [ -# { -# "match": { -# "name": "%s" % (trait.name) -# } -# }, -# { -# "match": { -# "dataset": "%s" % (dataset.name) -# } -# } -# ] -# } -# } -# } - -# response = es.search( index = "traits", doc_type = "trait", body = es_body ) -# logger.info("THE RESPONSE:", response) -# results = response['hits']['hits'] - -# if len(results) > 0: -# samples = results[0]['_source']['samples'] - -# sample_dict = {} -# for sample in samples: -# sample_dict[sample['name']] = sample['qnorm'] - -# #logger.info("SAMPLE DICT:", sample_dict) -# return sample_dict -# else: -# return None - def natural_sort_key(x): """Get expected results when using as a key for sort - ints or strings are sorted properly""" diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index f188fd9d..30b03e66 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -43,8 +43,6 @@ logger = getLogger(__name__ ) class ShowTrait(object): def __init__(self, kw): - logger.debug("in ShowTrait, kw are:", kw) - if 'trait_id' in kw and kw['dataset'] != "Temp": self.temp_trait = False self.trait_id = kw['trait_id'] @@ -152,6 +150,7 @@ class ShowTrait(object): #self.nearest_marker1 = "" #self.nearest_marker2 = "" + self.make_sample_lists() self.qnorm_vals = quantile_normalize_vals(self.sample_groups) @@ -275,7 +274,9 @@ class ShowTrait(object): data_scale = self.dataset.data_scale, sample_group_types = self.sample_group_types, sample_lists = sample_lists, - attribute_names = self.sample_groups[0].attributes, + se_exists = self.sample_groups[0].se_exists, + has_num_cases = self.has_num_cases, + attributes = self.sample_groups[0].attributes, categorical_vars = ",".join(categorical_var_list), num_values = self.num_values, qnorm_values = self.qnorm_vals, @@ -395,6 +396,7 @@ class ShowTrait(object): return_results_menu_selected = return_results_menu_selected,) def make_sample_lists(self): + all_samples_ordered = self.dataset.group.all_samples_ordered() parent_f1_samples = [] @@ -403,13 +405,18 @@ class ShowTrait(object): primary_sample_names = list(all_samples_ordered) + if not self.temp_trait: other_sample_names = [] - for sample in self.this_trait.data.keys(): - if (self.this_trait.data[sample].name2 in primary_sample_names) and (self.this_trait.data[sample].name not in primary_sample_names): - primary_sample_names.append(self.this_trait.data[sample].name) - primary_sample_names.remove(self.this_trait.data[sample].name2) - elif sample not in all_samples_ordered: + + for sample in self.this_trait.data: + if self.this_trait.data[sample].name2 != self.this_trait.data[sample].name: + if (self.this_trait.data[sample].name2 in primary_sample_names) and (self.this_trait.data[sample].name not in primary_sample_names): + primary_sample_names.append(self.this_trait.data[sample].name) + primary_sample_names.remove(self.this_trait.data[sample].name2) + + all_samples_set = set(all_samples_ordered) + if sample not in all_samples_set: all_samples_ordered.append(sample) other_sample_names.append(sample) @@ -422,6 +429,7 @@ class ShowTrait(object): primary_header = "%s Only" % (self.dataset.group.name) else: primary_header = "Samples" + primary_samples = SampleList(dataset = self.dataset, sample_names=primary_sample_names, this_trait=self.this_trait, @@ -454,6 +462,7 @@ class ShowTrait(object): self.primary_sample_names = primary_sample_names self.dataset.group.allsamples = all_samples_ordered + def quantile_normalize_vals(sample_groups): def normf(trait_vals): ranked_vals = ss.rankdata(trait_vals) @@ -492,6 +501,7 @@ def quantile_normalize_vals(sample_groups): return qnorm_by_group + def get_z_scores(sample_groups): zscore_by_group = [] for sample_type in sample_groups: @@ -516,11 +526,10 @@ def get_z_scores(sample_groups): return zscore_by_group + def get_nearest_marker(this_trait, this_db): this_chr = this_trait.locus_chr - logger.debug("this_chr:", this_chr) this_mb = this_trait.locus_mb - logger.debug("this_mb:", this_mb) #One option is to take flanking markers, another is to take the two (or one) closest query = """SELECT Geno.Name FROM Geno, GenoXRef, GenoFreeze @@ -531,7 +540,6 @@ def get_nearest_marker(this_trait, this_db): ORDER BY ABS( Geno.Mb - {}) LIMIT 1""".format(this_chr, this_db.group.name+"Geno", this_mb) logger.sql(query) result = g.db.execute(query).fetchall() - logger.debug("result:", result) if result == []: return "" @@ -539,13 +547,14 @@ def get_nearest_marker(this_trait, this_db): else: return result[0][0] + def get_table_widths(sample_groups, has_num_cases=False): stats_table_width = 250 if len(sample_groups) > 1: stats_table_width = 450 trait_table_width = 380 - if sample_groups[0].se_exists(): + if sample_groups[0].se_exists: trait_table_width += 80 if has_num_cases: trait_table_width += 80 @@ -555,6 +564,7 @@ def get_table_widths(sample_groups, has_num_cases=False): return stats_table_width, trait_table_width + def has_num_cases(this_trait): has_n = False if this_trait.dataset.type != "ProbeSet" and this_trait.dataset.type != "Geno": @@ -565,6 +575,7 @@ def has_num_cases(this_trait): return has_n + def get_trait_units(this_trait): unit_type = "" inside_brackets = False @@ -584,6 +595,7 @@ def get_trait_units(this_trait): return unit_type + def check_if_attr_exists(the_trait, id_type): if hasattr(the_trait, id_type): if getattr(the_trait, id_type) == None or getattr(the_trait, id_type) == "": @@ -593,6 +605,7 @@ def check_if_attr_exists(the_trait, id_type): else: return False + def get_ncbi_summary(this_trait): if check_if_attr_exists(this_trait, 'geneid'): #ZS: Need to switch this try/except to something that checks the output later @@ -605,6 +618,7 @@ def get_ncbi_summary(this_trait): else: return None + def get_categorical_variables(this_trait, sample_list): categorical_var_list = [] @@ -623,6 +637,7 @@ def get_categorical_variables(this_trait, sample_list): return categorical_var_list + def get_genotype_scales(genofiles): geno_scales = {} if type(genofiles) is list: @@ -634,6 +649,7 @@ def get_genotype_scales(genofiles): return geno_scales + def get_scales_from_genofile(file_location): geno_path = locate_ignore_error(file_location, 'genotype') @@ -686,6 +702,7 @@ def get_scales_from_genofile(file_location): if i > first_marker_line + 10: break + #ZS: This assumes that both won't be all zero, since if that's the case mapping shouldn't be an option to begin with if mb_all_zero: return [["morgan", "cM"]] diff --git a/wqflask/wqflask/static/new/css/show_trait.css b/wqflask/wqflask/static/new/css/show_trait.css index 92deab20..7a7f5455 100644 --- a/wqflask/wqflask/static/new/css/show_trait.css +++ b/wqflask/wqflask/static/new/css/show_trait.css @@ -48,6 +48,13 @@ table.dataTable.cell-border tbody tr td:first-child { border-left: 1px solid #ccc; } +.checkbox { + min-height: 20px; +} + +.trait_value_input { + text-align: right; + .glyphicon { position: relative; top: 2px; diff --git a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js new file mode 100644 index 00000000..97b71306 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js @@ -0,0 +1,222 @@ +// ZS: 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; +if (js_data.se_exists) { + attribute_start_pos += 2; +} +if (js_data.has_num_cases === true) { + attribute_start_post += 1; +} + +build_columns = function() { + let column_list = [ + { + 'data': null, + 'orderDataType': "dom-checkbox", + 'searchable' : false, + 'render': function(data, type, row, meta) { + return '<input type="checkbox" name="searchResult" class="checkbox edit_sample_checkbox" value="">' + } + }, + { + 'title': "ID", + 'type': "natural", + 'searchable' : false, + 'data': "this_id" + }, + { + 'title': "Sample", + 'type': "natural", + 'data': null, + 'render': function(data, type, row, meta) { + return '<span class="edit_sample_sample_name">' + data.name + '</span>' + } + }, + { + 'title': "<div style='text-align: right;'>Value</div>", + 'orderDataType': "dom-input", + 'type': "cust-txt", + 'data': null, + 'render': function(data, type, row, meta) { + 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=6 maxlength=6>' + } else { + return '<input type="text" data-value="' + data.value.toFixed(3) + '" data-qnorm="' + js_data['qnorm_values'][0][parseInt(data.this_id) - 1] + '" data-zscore="' + js_data['zscore_values'][0][parseInt(data.this_id) - 1] + '" name="value:' + data.name + '" class="trait_value_input edit_sample_value" value="' + data.value.toFixed(3) + '" size=6 maxlength=6>' + } + } + } + ]; + + if (js_data.se_exists) { + column_list.push( + { + 'bSortable': false, + 'type': "natural", + 'data': null, + 'searchable' : false, + 'render': function(data, type, row, meta) { + return '±' + } + }, + { + 'title': "<div style='text-align: right;'>SE</div>", + 'orderDataType': "dom-input", + 'type': "cust-txt", + 'data': null, + 'render': function(data, type, row, meta) { + 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 maxlength=6>' + } else { + return '<input type="text" data-value="' + data.variance.toFixed(3) + '" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" class="trait_value_input edit_sample_se" value="' + data.variance.toFixed(3) + '" size=6 maxlength=6>' + } + } + } + ); + } + + if (js_data.has_num_cases === "true") { + column_list.push( + { + 'title': "<div style='text-align: right;'>N</div>", + 'orderDataType': "dom-input", + 'type': "cust-txt", + 'data': null, + 'render': function(data, type, row, meta) { + 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 { + return '<input type="text" data-value="' + data.num_cases + '" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" class="trait_value_input edit_sample_num_cases" value="' + data.num_cases + '" size=4 maxlength=4>' + } + } + } + ); + } + + attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].name > js_data.attributes[b].name) ? 1 : -1) + for (i = 0; i < attr_keys.length; i++){ + column_list.push( + { + 'title': "<div style='text-align: " + js_data.attributes[attr_keys[i]].alignment + "'>" + js_data.attributes[attr_keys[i]].name + "</div>", + 'type': "natural", + 'data': null, + 'render': function(data, type, row, meta) { + attr_name = Object.keys(data.extra_attributes).sort((a, b) => (a > b) ? 1 : -1)[meta.col - data.first_attr_col] + if (attr_name != null && attr_name != undefined){ + return data.extra_attributes[attr_name] + } else { + return "" + } + } + } + ) + } + + return column_list +} + +var primary_table = $('#samples_primary').DataTable( { + 'initComplete': function(settings, json) { + $('.edit_sample_value').change(function() { + edit_data_change(); + }); + }, + 'createdRow': function ( row, data, index ) { + $(row).attr('id', "Primary_" + data.this_id) + $(row).addClass("value_se"); + if (data.outlier) { + $(row).addClass("outlier"); + } + $('td', row).eq(1).addClass("column_name-Index") + $('td', row).eq(2).addClass("column_name-Sample") + $('td', row).eq(3).addClass("column_name-Value") + if (js_data.se_exists) { + $('td', row).eq(5).addClass("column_name-SE") + if (js_data.has_num_cases === "true") { + $('td', row).eq(6).addClass("column_name-num_cases") + } else { + if (js_data.has_num_cases === "true") { + $('td', row).eq(4).addClass("column_name-num_cases") + } + } + } else { + if (js_data.has_num_cases === "true") { + $('td', row).eq(4).addClass("column_name-num_cases") + } + } + + sorted_key_list = Object.keys(js_data.attributes).sort() + for (i=0; i < sorted_key_list.length; i++) { + $('td', row).eq(attribute_start_pos + i + 1).addClass("column_name-" + js_data.attributes[sorted_key_list[i]].name) + $('td', row).eq(attribute_start_pos + i + 1).attr("style", "text-align: " + js_data.attributes[sorted_key_list[i]].alignment + "; padding-top: 2px; padding-bottom: 0px;") + } + }, + 'data': js_data['sample_lists'][0], + 'columns': build_columns(), + 'order': [[1, "asc"]], + 'sDom': "Ztr", + 'autoWidth': true, + 'orderClasses': true, + "scrollY": "50vh", + 'scroller': true, + 'scrollCollapse': true +} ); + +primary_table.on( 'order.dt search.dt draw.dt', function () { + primary_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { + cell.innerHTML = i+1; + } ); +} ).draw(); + +$('#primary_searchbox').on( 'keyup', function () { + primary_table.search($(this).val()).draw(); +} ); + +if (js_data.sample_lists.length > 1){ + var other_table = $('#samples_other').DataTable( { + 'initComplete': function(settings, json) { + $('.edit_sample_value').change(function() { + edit_data_change(); + }); + }, + 'createdRow': function ( row, data, index ) { + $(row).attr('id', "Primary_" + data.this_id) + $(row).addClass("value_se"); + if (data.outlier) { + $(row).addClass("outlier"); + } + $('td', row).eq(1).addClass("column_name-Index") + $('td', row).eq(2).addClass("column_name-Sample") + $('td', row).eq(3).addClass("column_name-Value") + if (js_data.se_exists) { + $('td', row).eq(5).addClass("column_name-SE") + if (js_data.has_num_cases === "true") { + $('td', row).eq(6).addClass("column_name-num_cases") + } else { + if (js_data.has_num_cases === "true") { + $('td', row).eq(4).addClass("column_name-num_cases") + } + } + } else { + if (js_data.has_num_cases === "true") { + $('td', row).eq(4).addClass("column_name-num_cases") + } + } + + sorted_key_list = Object.keys(js_data.attributes).sort() + for (i=0; i < sorted_key_list.length; i++) { + $('td', row).eq(attribute_start_pos + i + 1).addClass("column_name-" + js_data.attributes[sorted_key_list[i]].name) + $('td', row).eq(attribute_start_pos + i + 1).attr("style", "text-align: " + js_data.attributes[sorted_key_list[i]].alignment + "; padding-top: 2px; padding-bottom: 0px;") + } + }, + 'data': js_data['sample_lists'][1], + 'columns': build_columns(), + 'order': [[1, "asc"]], + 'sDom': "Ztr", + 'autoWidth': true, + 'orderClasses': true, + "scrollY": "50vh", + 'scroller': true, + 'scrollCollapse': true + } ); +}
\ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index c0784073..eaad0a4c 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -440,38 +440,47 @@ edit_data_change = function() { samples_other: {}, samples_all: {} }; + tables = ['samples_primary', 'samples_other']; for (_i = 0, _len = tables.length; _i < _len; _i++) { table = tables[_i]; - rows = $("#" + table).find('tr'); - for (_j = 0, _len1 = rows.length; _j < _len1; _j++) { - row = rows[_j]; - name = $(row).find('.edit_sample_sample_name').html(); - name = $.trim(name); - real_value = $(row).find('.edit_sample_value').val(); - checkbox = $(row).find(".edit_sample_checkbox"); - if (is_number(real_value) && real_value !== "") { - real_value = parseFloat(real_value); - sample_sets[table].add_value(real_value); - real_variance = $(row).find('.edit_sample_se').val(); - if (is_number(real_variance)) { - real_variance = parseFloat(real_variance); - } else { - real_variance = null; - } - real_dict = { - value: real_value, - variance: real_variance - }; - root.selected_samples[table][name] = real_dict; - if (!(name in already_seen)) { - sample_sets['samples_all'].add_value(real_value); - root.selected_samples['samples_all'][name] = real_dict; - already_seen[name] = true; + if ($('#' + table).length){ + table_api = $('#' + 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$(); + 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 !== "") { + sample_val = parseFloat(sample_val); + sample_sets[table].add_value(sample_val); + if (typeof var_nodes !== 'undefined'){ + sample_var = null; + } else { + sample_var = var_nodes[_j].childNodes[0].value + if (is_number(sample_var)) { + sample_var = parseFloat(sample_var) + } else { + sample_var = null; + } + } + sample_dict = { + value: sample_val, + variance: sample_var + } + root.selected_samples[table][sample_name] = sample_dict; + if (!(sample_name in already_seen)) { + sample_sets['samples_all'].add_value(sample_val); + root.selected_samples['samples_all'][sample_name] = sample_dict; + already_seen[sample_name] = true; + } } } } } + update_stat_values(sample_sets); if ($('#histogram').hasClass('js-plotly-plot')){ @@ -490,6 +499,7 @@ edit_data_change = function() { return update_prob_plot(); } }; + show_hide_outliers = function() { var label; label = $('#show_hide_outliers').val(); @@ -500,6 +510,7 @@ show_hide_outliers = function() { return console.log("Should be now Hide Outliers"); } }; + on_corr_method_change = function() { var corr_method; corr_method = $('select[name=corr_type]').val(); @@ -514,10 +525,30 @@ on_corr_method_change = function() { $('select[name=corr_type]').change(on_corr_method_change); submit_special = function(url) { + get_table_contents_for_form_submit("trait_data_form"); $("#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 = ['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', 'loc_chr', 'min_loc_mb', 'max_loc_mb', 'p_range_lower', 'p_range_upper'] @@ -538,10 +569,9 @@ populate_sample_attributes_values_dropdown = function() { var attribute_info, key, sample_attributes, selected_attribute, value, _i, _len, _ref, _ref1, _results; $('#attribute_values').empty(); sample_attributes = {}; - _ref = js_data.attribute_names; - for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; - attribute_info = _ref[key]; + attr_keys = Object.keys(js_data.attributes).sort(); + for (i=0; i < attr_keys.length; i++) { + attribute_info = js_data.attributes[attr_keys[i]]; sample_attributes[attribute_info.name] = attribute_info.distinct_values; } selected_attribute = $('#exclude_menu').val().replace("_", " "); @@ -549,13 +579,17 @@ populate_sample_attributes_values_dropdown = function() { _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { value = _ref1[_i]; - _results.push($(create_value_dropdown(value)).appendTo($('#attribute_values'))); + if (value != ""){ + _results.push($(create_value_dropdown(value)).appendTo($('#attribute_values'))); + } } return _results; }; -if (Object.keys(js_data.attribute_names).length > 0) { + +if (Object.keys(js_data.attributes).length){ populate_sample_attributes_values_dropdown(); } + $('#exclude_menu').change(populate_sample_attributes_values_dropdown); block_by_attribute_value = function() { var attribute_name, cell_class, exclude_by_value; @@ -580,20 +614,6 @@ block_by_index = function() { _ref = index_string.split(","); for (_i = 0, _len = _ref.length; _i < _len; _i++) { index_set = _ref[_i]; - /* - if (index_set.indexOf('<') !== -1) { - try { - start_index = parseInt(index_set.split("<")[0]); - end_index = parseInt(index_set.split("<")[1]); - for (index = _j = start_index; start_index <= end_index ? _j <= end_index : _j >= end_index; index = start_index <= end_index ? ++_j : --_j) { - index_list.push(index); - } - } catch (_error) { - error = _error; - alert("Syntax error"); - } - } - */ if (index_set.indexOf('-') !== -1) { try { start_index = parseInt(index_set.split("-")[0]); @@ -611,19 +631,18 @@ block_by_index = function() { } } _results = []; + let block_group = $('#block_group').val(); + if (block_group === "other") { + table_api = $('#samples_other').DataTable(); + } else { + table_api = $('#samples_primary').DataTable(); + } + val_nodes = table_api.column(3).nodes().to$(); for (_k = 0, _len1 = index_list.length; _k < _len1; _k++) { index = index_list[_k]; - if ($('#block_group').val() === "primary") { - _results.push($('#samples_primary').find('td.column_name-Index').filter(function() { return $(this).text() == index.toString() }).closest('tr').find('.trait_value_input').val("x")); - } else if ($('#block_group').val() === "other") { - _results.push($('#samples_other').find('td.column_name-Index').filter(function() { return $(this).text() == index.toString() }).closest('tr').find('.trait_value_input').val("x")); - } else { - _results.push(void 0); - } + val_nodes[index - 1].childNodes[0].value = "x"; } - return _results; }; -$('#block_by_index').click(block_by_index); hide_no_value = function() { return $('.value_se').each((function(_this) { @@ -635,6 +654,7 @@ hide_no_value = function() { })(this)); }; $('#hide_no_value').click(hide_no_value); + block_outliers = function() { return $('.outlier').each((function(_this) { return function(_index, element) { @@ -643,177 +663,195 @@ block_outliers = function() { })(this)); }; $('#block_outliers').click(block_outliers); + reset_samples_table = function() { $('input[name="transform"]').val(""); $('span[name="transform_text"]').text("") - return $('.trait_value_input').each((function(_this) { - return function(_index, element) { - $(element).val($(element).data('value')); - return $(element).parents('.value_se').show(); - }; - })(this)); + + 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$(); + 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$(); + for (i = 0; i < val_nodes.length; i++) { + this_node = val_nodes[i].childNodes[0]; + this_node.value = this_node.attributes["data-value"].value; + } + } + } + } }; $('.reset').click(function() { reset_samples_table(); edit_data_change(); }); -log2_normalize_data = function(zero_to_one_vals_exist) { - return $('.trait_value_input').each((function(_this) { - return function(_index, element) { - current_value = $(element).data("value") - if(isNaN(current_value)) { - return current_value - } else { - if (zero_to_one_vals_exist){ - current_value = parseFloat(current_value) + 1; +check_for_zero_to_one_vals = 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$(); + for (i = 0; i < val_nodes.length; i++) { + this_node = val_nodes[i].childNodes[0]; + if(!isNaN(this_node.value)) { + if (0 <= this_node.value && this_node.value < 1){ + return true + } } - $(element).val(Math.log2(current_value).toFixed(3)); - return Math.log2(current_value).toFixed(3) } - }; - })(this)); -}; + } + } + return false +} -log10_normalize_data = function(zero_to_one_vals_exist) { - return $('.trait_value_input').each((function(_this) { - return function(_index, element) { - current_value = $(element).data("value") - if(isNaN(current_value)) { - return current_value - } else { - if (zero_to_one_vals_exist){ - current_value = parseFloat(current_value) + 1; - } - $(element).val(Math.log10(current_value).toFixed(3)); - return Math.log10(current_value).toFixed(3) - } - }; - })(this)); +log2_data = 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){ + original_value = parseFloat(original_value) + 1; + } + this_node.value = Math.log2(original_value).toFixed(3); + } }; +log10_data = 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){ + original_value = parseFloat(original_value) + 1; + } + this_node.value = Math.log10(original_value).toFixed(3); + } +}; -sqrt_normalize_data = function() { - return $('.edit_sample_value').each((function(_this) { - return function(_index, element) { - current_value = parseFloat($(element).data("value")) + 1; - if(isNaN(current_value)) { - return current_value - } else { - $(element).val(Math.sqrt(current_value).toFixed(3)); - return Math.sqrt(current_value).toFixed(3) - } - }; - })(this)); +sqrt_data = 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){ + original_value = parseFloat(original_value) + 1; + } + this_node.value = Math.sqrt(original_value).toFixed(3); + } }; invert_data = function() { - return $('.edit_sample_value').each((function(_this) { - return function(_index, element) { - current_value = parseFloat($(element).val()); - if(isNaN(current_value)) { - return current_value - } else { - $(element).val(-(current_value)); - return -(current_value) - } - }; - })(this)); + current_value = this_node.value; + if(!isNaN(current_value)) { + this_node.value = parseFloat(-(current_value)).toFixed(3); + } }; - qnorm_data = function() { - return $('.edit_sample_value').each((function(_this) { - return function(_index, element) { - current_value = parseFloat($(element).data("value")) + 1; - if(isNaN(current_value)) { - return current_value - } else { - $(element).val($(element).data("qnorm")); - return $(element).data("qnorm"); - } - }; - })(this)); + current_value = this_node.value; + qnorm_value = this_node.attributes['data-qnorm'].value; + if(!isNaN(current_value)) { + this_node.value = qnorm_value; + } }; zscore_data = function() { - return $('.edit_sample_value').each((function(_this) { - return function(_index, element) { - current_value = parseFloat($(element).data("value")) + 1; - if(isNaN(current_value)) { - return current_value - } else { - $(element).val($(element).data("zscore")); - return $(element).data("zscore"); - } - }; - })(this)); + current_value = this_node.value; + zscore_value = this_node.attributes['data-zscore'].value; + if(!isNaN(current_value)) { + this_node.value = zscore_value; + } }; -check_for_zero_to_one_vals = function() { - zero_to_one_vals_exist = false - $('.trait_value_input').each(function() { - current_value = $(this).data("value") - if(isNaN(current_value)) { - return true; - } else { - current_value = parseFloat(current_value) - if (0 <= current_value && current_value < 1){ - zero_to_one_vals_exist = true - return false +do_transform = 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$(); + for (i = 0; i < val_nodes.length; i++) { + this_node = val_nodes[i].childNodes[0] + if (transform_type == "log2"){ + log2_data(this_node) + } + if (transform_type == "log10"){ + log10_data(this_node) + } + if (transform_type == "sqrt"){ + sqrt_data(this_node) + } + if (transform_type == "invert"){ + invert_data(this_node) + } + if (transform_type == "qnorm"){ + qnorm_data(this_node) + } + if (transform_type == "zscore"){ + zscore_data(this_node) + } } } - }); - return zero_to_one_vals_exist + } } normalize_data = 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') { - log2_normalize_data(zero_to_one_vals_exist) + do_transform("log2") $('input[name="transform"]').val("log2") - $('span[name="transform_text"]').text(" - log2 transformed") + $('span[name="transform_text"]').text(" - log2 Transformed") } else { if ($('input[name="transform"]').val() != "log10" && $('#norm_method option:selected').val() == 'log10'){ - log10_normalize_data(zero_to_one_vals_exist) + do_transform("log10") $('input[name="transform"]').val("log10") - $('span[name="transform_text"]').text(" - log10 transformed") + $('span[name="transform_text"]').text(" - log10 Transformed") } } } else if ($('#norm_method option:selected').val() == 'sqrt'){ if ($('input[name="transform"]').val() != "sqrt") { - sqrt_normalize_data() + do_transform("sqrt") $('input[name="transform"]').val("sqrt") - $('span[name="transform_text"]').text(" - Square Root transformed") + $('span[name="transform_text"]').text(" - Square Root Transformed") } } else if ($('#norm_method option:selected').val() == 'invert'){ - invert_data() + do_transform("invert") $('input[name="transform"]').val("inverted") - $('span[name="transform_text"]').text(" - Inverted") + if ($('span[name="transform_text"]:eq(0)').text() != ""){ + current_text = $('span[name="transform_text"]:eq(0)').text(); + $('span[name="transform_text"]').text(current_text + " and Inverted"); + } else { + $('span[name="transform_text"]').text(" - Inverted") + } } else if ($('#norm_method option:selected').val() == 'qnorm'){ if ($('input[name="transform"]').val() != "qnorm") { - qnorm_data() + do_transform("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") { - zscore_data() + do_transform("zscore") $('input[name="transform"]').val("zscore") $('span[name="transform_text"]').text(" - Z-Scores") } } } -zero_to_one_vals_exist = false +zero_to_one_vals_exist = check_for_zero_to_one_vals(); show_transform_warning = function() { transform_type = $('#norm_method option:selected').val() - zero_to_one_vals_exist = check_for_zero_to_one_vals(); if (transform_type == "log2" || transform_type == "log10"){ if (zero_to_one_vals_exist){ $('#transform_alert').css("display", "block") @@ -859,10 +897,9 @@ get_sample_table_data = function(table_name) { if ($(element).find('.edit_sample_num_cases').length > 0) { row_data.num_cases = $(element).find('.edit_sample_num_cases').val(); } - _ref = js_data.attribute_names; - for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; - attribute_info = _ref[key]; + attr_keys = Object.keys(js_data.attributes).sort() + for (i=0; i < attr_keys.length; i++) { + attribute_info = js_data.attributes[attr_keys[i]]; row_data[attribute_info.name] = $.trim($(element).find('.column_name-' + attribute_info.name.replace(" ", "_").replace("/", "\\/")).text()); } return samples.push(row_data); @@ -1447,8 +1484,11 @@ $('.stats_panel').click(function() { edit_data_change(); } }); -$('#edit_sample_lists').change(edit_data_change); -$('#block_by_index').click(edit_data_change); + +$('#block_by_index').click(function(){ + block_by_index(); + edit_data_change(); +}); $('#exclude_group').click(edit_data_change); $('#block_outliers').click(edit_data_change); $('#reset').click(edit_data_change); diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js index 4dce0705..c0f36eaa 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -1,307 +1,298 @@ -// Generated by CoffeeScript 1.8.0 -(function() { - var block_outliers, composite_mapping_fields, do_ajax_post, get_progress, mapping_method_fields, open_mapping_results, outlier_text, showalert, submit_special, toggle_enable_disable, update_time_remaining; +var block_outliers, composite_mapping_fields, do_ajax_post, get_progress, mapping_method_fields, open_mapping_results, outlier_text, showalert, submit_special, toggle_enable_disable, update_time_remaining; - submit_special = function(url) { - $("#trait_data_form").attr("action", url); - $("#trait_data_form").submit(); - }; - - update_time_remaining = function(percent_complete) { - var minutes_remaining, now, period, total_seconds_remaining; - now = new Date(); - period = now.getTime() - root.start_time; - console.log("period is:", period); - if (period > 8000) { - total_seconds_remaining = (period / percent_complete * (100 - percent_complete)) / 1000; - minutes_remaining = Math.round(total_seconds_remaining / 60); - if (minutes_remaining < 3) { - return $('#time_remaining').text(Math.round(total_seconds_remaining) + " seconds remaining"); - } else { - return $('#time_remaining').text(minutes_remaining + " minutes remaining"); - } +update_time_remaining = function(percent_complete) { + var minutes_remaining, now, period, total_seconds_remaining; + now = new Date(); + period = now.getTime() - root.start_time; + console.log("period is:", period); + if (period > 8000) { + total_seconds_remaining = (period / percent_complete * (100 - percent_complete)) / 1000; + minutes_remaining = Math.round(total_seconds_remaining / 60); + if (minutes_remaining < 3) { + return $('#time_remaining').text(Math.round(total_seconds_remaining) + " seconds remaining"); + } else { + return $('#time_remaining').text(minutes_remaining + " minutes remaining"); } - }; + } +}; - get_progress = function() { - var params, params_str, temp_uuid, url; - console.log("temp_uuid:", $("#temp_uuid").val()); - temp_uuid = $("#temp_uuid").val(); - params = { - key: temp_uuid - }; - params_str = $.param(params); - url = "/get_temp_data?" + params_str; - console.log("url:", url); - $.ajax({ - type: "GET", - url: url, - success: (function(_this) { - return function(progress_data) { - var percent_complete; - percent_complete = progress_data['percent_complete']; - console.log("in get_progress data:", progress_data); - $('#marker_regression_progress').css("width", percent_complete + "%"); - if (root.start_time) { - if (!isNaN(percent_complete)) { - return update_time_remaining(percent_complete); - } - } else { - return root.start_time = new Date().getTime(); - } - }; - })(this) - }); - return false; +get_progress = function() { + var params, params_str, temp_uuid, url; + console.log("temp_uuid:", $("#temp_uuid").val()); + temp_uuid = $("#temp_uuid").val(); + params = { + key: temp_uuid }; - - block_outliers = function() { - return $('.outlier').each((function(_this) { - return function(_index, element) { - return $(element).find('.trait_value_input').val('x'); + params_str = $.param(params); + url = "/get_temp_data?" + params_str; + console.log("url:", url); + $.ajax({ + type: "GET", + url: url, + success: (function(_this) { + return function(progress_data) { + var percent_complete; + percent_complete = progress_data['percent_complete']; + console.log("in get_progress data:", progress_data); + $('#marker_regression_progress').css("width", percent_complete + "%"); + if (root.start_time) { + if (!isNaN(percent_complete)) { + return update_time_remaining(percent_complete); + } + } else { + return root.start_time = new Date().getTime(); + } }; - })(this)); - }; - - do_ajax_post = function(url, form_data) { - $.ajax({ - type: "POST", - url: url, - data: form_data, - error: (function(_this) { - return function(xhr, ajaxOptions, thrownError) { - alert("Sorry, an error occurred"); - console.log(xhr); - clearInterval(_this.my_timer); - $('#progress_bar_container').modal('hide'); - $('#static_progress_bar_container').modal('hide'); - return $("body").html("We got an error."); - }; - })(this), - success: (function(_this) { - return function(data) { - clearInterval(_this.my_timer); - $('#progress_bar_container').modal('hide'); - $('#static_progress_bar_container').modal('hide'); - return open_mapping_results(data); - }; - })(this) - }); - console.log("settingInterval"); - this.my_timer = setInterval(get_progress, 1000); - return false; - }; - - open_mapping_results = function(data) { - return $.colorbox({ - html: data, - href: "#mapping_results_holder", - height: "90%", - width: "90%", - onComplete: (function(_this) { - return function() { - var filename, getSvgXml; - root.create_lod_chart(); - filename = "lod_chart_" + js_data.this_trait; - getSvgXml = function() { - var svg; - svg = $("#topchart").find("svg")[0]; - return (new XMLSerializer).serializeToString(svg); - }; - $("#exportform > #export").click(function() { - var form, svg_xml; - svg_xml = getSvgXml(); - form = $("#exportform"); - form.find("#data").val(svg_xml); - form.find("#filename").val(filename); - return form.submit(); - }); - return $("#exportpdfform > #export_pdf").click(function() { - var form, svg_xml; - svg_xml = getSvgXml(); - form = $("#exportpdfform"); - form.find("#data").val(svg_xml); - form.find("#filename").val(filename); - return form.submit(); - }); - }; - })(this) - }); - }; - - outlier_text = "One or more outliers exist in this data set. Please review values before mapping. Including outliers when mapping may lead to misleading results."; - showalert = function(message, alerttype) { - return $('#outlier_alert_placeholder').append('<div id="mapping_alert" class="alert ' + alerttype + '"><a class="close" data-dismiss="alert">�</a><span>' + message + '</span></div>'); - }; - - $('#suggestive').hide(); + })(this) + }); + return false; +}; - $('input[name=display_all]').change((function(_this) { - return function() { - console.log("check"); - if ($('input[name=display_all]:checked').val() === "False") { - return $('#suggestive').show(); - } else { - return $('#suggestive').hide(); - } +block_outliers = function() { + return $('.outlier').each((function(_this) { + return function(_index, element) { + return $(element).find('.trait_value_input').val('x'); }; })(this)); +}; - //ZS: This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping - var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', - 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results', - 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker', 'control_marker_db', 'do_control', 'genofile', - 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck', - 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'reaper_version', 'primary_samples'] - - $(".rqtl_tab, #rqtl_geno_compute").on("click", (function(_this) { - return function() { - if ($(this).hasClass('active') || $(this).attr('id') == "rqtl_geno_compute"){ - var form_data, url; - url = "/loading"; - $('input[name=method]').val("rqtl_geno"); - $('input[name=selected_chr]').val($('#chr_rqtl_geno').val()); - $('input[name=mapping_scale]').val($('#scale_rqtl_geno').val()); - $('input[name=genofile]').val($('#genofile_rqtl_geno').val()); - $('input[name=num_perm]').val($('input[name=num_perm_rqtl_geno]').val()); - $('input[name=categorical_vars]').val(js_data.categorical_vars) - $('input[name=manhattan_plot]').val($('input[name=manhattan_plot_rqtl]:checked').val()); - $('input[name=control_marker]').val($('input[name=control_rqtl_geno]').val()); - $('input[name=do_control]').val($('input[name=do_control_rqtl]:checked').val()); - $('input[name=tool_used]').val("Mapping"); - $('input[name=form_url]').val("/run_mapping"); - $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); - return submit_special(url); - } else { - return true - } - }; - })(this)); - - $(".gemma_tab, #gemma_compute").on("click", (function(_this) { - return function() { - if ($(this).hasClass('active') || $(this).attr('id') == "gemma_compute"){ - var form_data, url; - console.log("RUNNING GEMMA"); - url = "/loading"; - $('input[name=method]').val("gemma"); - $('input[name=selected_chr]').val($('#chr_gemma').val()); - $('input[name=num_perm]').val(0); - $('input[name=genofile]').val($('#genofile_gemma').val()); - $('input[name=maf]').val($('input[name=maf_gemma]').val()); - $('input[name=tool_used]').val("Mapping"); - $('input[name=form_url]').val("/run_mapping"); - $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); - return submit_special(url); - } else { - return true - } - }; - })(this)); +do_ajax_post = function(url, form_data) { + $.ajax({ + type: "POST", + url: url, + data: form_data, + error: (function(_this) { + return function(xhr, ajaxOptions, thrownError) { + alert("Sorry, an error occurred"); + console.log(xhr); + clearInterval(_this.my_timer); + $('#progress_bar_container').modal('hide'); + $('#static_progress_bar_container').modal('hide'); + return $("body").html("We got an error."); + }; + })(this), + success: (function(_this) { + return function(data) { + clearInterval(_this.my_timer); + $('#progress_bar_container').modal('hide'); + $('#static_progress_bar_container').modal('hide'); + return open_mapping_results(data); + }; + })(this) + }); + console.log("settingInterval"); + this.my_timer = setInterval(get_progress, 1000); + return false; +}; - $(".reaper_tab, #interval_mapping_compute").on("click", (function(_this) { - return function() { - if ($(this).hasClass('active') || $(this).attr('id') == "interval_mapping_compute"){ - var form_data, url; - console.log("In interval mapping"); - url = "/loading"; - $('input[name=method]').val("reaper"); - $('input[name=selected_chr]').val($('#chr_reaper').val()); - $('input[name=mapping_scale]').val($('#scale_reaper').val()); - $('input[name=genofile]').val($('#genofile_reaper').val()); - $('input[name=num_perm]').val($('input[name=num_perm_reaper]').val()); - $('input[name=control_marker]').val($('input[name=control_reaper]').val()); - $('input[name=do_control]').val($('input[name=do_control_reaper]:checked').val()); - $('input[name=manhattan_plot]').val($('input[name=manhattan_plot_reaper]:checked').val()); - $('input[name=mapping_display_all]').val($('input[name=display_all_reaper]')); - $('input[name=suggestive]').val($('input[name=suggestive_reaper]')); - $('input[name=tool_used]').val("Mapping"); - $('input[name=form_url]').val("/run_mapping"); - $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); - return submit_special(url); - } else { - return true - } - }; - })(this)); +open_mapping_results = function(data) { + return $.colorbox({ + html: data, + href: "#mapping_results_holder", + height: "90%", + width: "90%", + onComplete: (function(_this) { + return function() { + var filename, getSvgXml; + root.create_lod_chart(); + filename = "lod_chart_" + js_data.this_trait; + getSvgXml = function() { + var svg; + svg = $("#topchart").find("svg")[0]; + return (new XMLSerializer).serializeToString(svg); + }; + $("#exportform > #export").click(function() { + var form, svg_xml; + svg_xml = getSvgXml(); + form = $("#exportform"); + form.find("#data").val(svg_xml); + form.find("#filename").val(filename); + return form.submit(); + }); + return $("#exportpdfform > #export_pdf").click(function() { + var form, svg_xml; + svg_xml = getSvgXml(); + form = $("#exportpdfform"); + form.find("#data").val(svg_xml); + form.find("#filename").val(filename); + return form.submit(); + }); + }; + })(this) + }); +}; - $("#interval_mapping_compute, #gemma_compute, rqtl_geno_compute").on("mouseover", (function(_this) { - return function() { - if ($(".outlier").length && $(".outlier-alert").length < 1) { - return showalert(outlier_text, "alert-success outlier-alert"); - } - }; - })(this)); +outlier_text = "One or more outliers exist in this data set. Please review values before mapping. Including outliers when mapping may lead to misleading results."; +showalert = function(message, alerttype) { + return $('#outlier_alert_placeholder').append('<div id="mapping_alert" class="alert ' + alerttype + '"><a class="close" data-dismiss="alert">�</a><span>' + message + '</span></div>'); +}; - composite_mapping_fields = function() { - return $(".composite_fields").toggle(); - }; +$('#suggestive').hide(); - mapping_method_fields = function() { - return $(".mapping_method_fields").toggle(); +$('input[name=display_all]').change((function(_this) { + return function() { + console.log("check"); + if ($('input[name=display_all]:checked').val() === "False") { + return $('#suggestive').show(); + } else { + return $('#suggestive').hide(); + } }; +})(this)); - $("#use_composite_choice").change(composite_mapping_fields); - - $("#mapping_method_choice").change(mapping_method_fields); +//ZS: This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping +var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', + 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results', + 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker', 'control_marker_db', 'do_control', 'genofile', + 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck', + 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'reaper_version', 'primary_samples'] - $("#mapmodel_rqtl_geno").change(function() { - if ($(this).val() == "np"){ - $("#mapmethod_rqtl_geno").attr('disabled', 'disabled'); - $("#mapmethod_rqtl_geno").css('background-color', '#CCC'); - $("#missing_geno").attr('disabled', 'disabled'); - $("#missing_geno").css('background-color', '#CCC'); +$(".rqtl_tab, #rqtl_geno_compute").on("click", (function(_this) { + return function() { + if ($(this).hasClass('active') || $(this).attr('id') == "rqtl_geno_compute"){ + var form_data, url; + url = "/loading"; + $('input[name=method]').val("rqtl_geno"); + $('input[name=selected_chr]').val($('#chr_rqtl_geno').val()); + $('input[name=mapping_scale]').val($('#scale_rqtl_geno').val()); + $('input[name=genofile]').val($('#genofile_rqtl_geno').val()); + $('input[name=num_perm]').val($('input[name=num_perm_rqtl_geno]').val()); + $('input[name=categorical_vars]').val(js_data.categorical_vars) + $('input[name=manhattan_plot]').val($('input[name=manhattan_plot_rqtl]:checked').val()); + $('input[name=control_marker]').val($('input[name=control_rqtl_geno]').val()); + $('input[name=do_control]').val($('input[name=do_control_rqtl]:checked').val()); + $('input[name=tool_used]').val("Mapping"); + $('input[name=form_url]').val("/run_mapping"); + $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); + return submit_special(url); } else { - $("#mapmethod_rqtl_geno").removeAttr('disabled'); - $("#mapmethod_rqtl_geno").css('background-color', '#FFF'); - $("#missing_geno").removeAttr('disabled'); - $("#missing_geno").css('background-color', '#FFF'); + return true } - }); + }; +})(this)); - $("#mapmethod_rqtl_geno").change(function() { - if ($(this).val() == "mr"){ - $("#missing_geno_div").css('display', 'block'); +$(".gemma_tab, #gemma_compute").on("click", (function(_this) { + return function() { + if ($(this).hasClass('active') || $(this).attr('id') == "gemma_compute"){ + var form_data, url; + console.log("RUNNING GEMMA"); + url = "/loading"; + $('input[name=method]').val("gemma"); + $('input[name=selected_chr]').val($('#chr_gemma').val()); + $('input[name=num_perm]').val(0); + $('input[name=genofile]').val($('#genofile_gemma').val()); + $('input[name=maf]').val($('input[name=maf_gemma]').val()); + $('input[name=tool_used]').val("Mapping"); + $('input[name=form_url]').val("/run_mapping"); + $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); + return submit_special(url); } else { - $("#missing_geno_div").css('display', 'none'); + return true } - }); + }; +})(this)); - $("li.mapping_tab").click(function() { - if ($(this).hasClass("rqtl")){ - $(".rqtl_description").css("display", "block"); +$(".reaper_tab, #interval_mapping_compute").on("click", (function(_this) { + return function() { + if ($(this).hasClass('active') || $(this).attr('id') == "interval_mapping_compute"){ + var form_data, url; + console.log("In interval mapping"); + url = "/loading"; + $('input[name=method]').val("reaper"); + $('input[name=selected_chr]').val($('#chr_reaper').val()); + $('input[name=mapping_scale]').val($('#scale_reaper').val()); + $('input[name=genofile]').val($('#genofile_reaper').val()); + $('input[name=num_perm]').val($('input[name=num_perm_reaper]').val()); + $('input[name=control_marker]').val($('input[name=control_reaper]').val()); + $('input[name=do_control]').val($('input[name=do_control_reaper]:checked').val()); + $('input[name=manhattan_plot]').val($('input[name=manhattan_plot_reaper]:checked').val()); + $('input[name=mapping_display_all]').val($('input[name=display_all_reaper]')); + $('input[name=suggestive]').val($('input[name=suggestive_reaper]')); + $('input[name=tool_used]').val("Mapping"); + $('input[name=form_url]').val("/run_mapping"); + $('input[name=wanted_inputs]').val(mapping_input_list.join(",")); + return submit_special(url); } else { - $(".rqtl_description").css("display", "none"); + return true } - }); + }; +})(this)); - toggle_enable_disable = function(elem) { - return $(elem).prop("disabled", !$(elem).prop("disabled")); +$("#interval_mapping_compute, #gemma_compute, rqtl_geno_compute").on("mouseover", (function(_this) { + return function() { + if ($(".outlier").length && $(".outlier-alert").length < 1) { + return showalert(outlier_text, "alert-success outlier-alert"); + } }; +})(this)); - $("#choose_closet_control").change(function() { - return toggle_enable_disable("#control_locus"); - }); +composite_mapping_fields = function() { + return $(".composite_fields").toggle(); +}; - $("#display_all_lrs").change(function() { - return toggle_enable_disable("#suggestive_lrs"); - }); +mapping_method_fields = function() { + return $(".mapping_method_fields").toggle(); +}; - $('#genofile_rqtl_geno').change(function() { - geno_location = $(this).children("option:selected").val().split(":")[0] - $('#scale_rqtl_geno').empty() - the_scales = js_data.scales_in_geno[geno_location] - for (var i = 0; i < the_scales.length; i++){ - $('#scale_rqtl_geno').append($("<option></option>").attr("value", the_scales[i][0]).text(the_scales[i][1])); - } - }); - $('#genofile_reaper').change(function() { - geno_location = $(this).children("option:selected").val().split(":")[0] - $('#scale_reaper').empty() - the_scales = js_data.scales_in_geno[geno_location] - for (var i = 0; i < the_scales.length; i++){ - $('#scale_reaper').append($("<option></option>").attr("value", the_scales[i][0]).text(the_scales[i][1])); - } - }); +$("#use_composite_choice").change(composite_mapping_fields); + +$("#mapping_method_choice").change(mapping_method_fields); + +$("#mapmodel_rqtl_geno").change(function() { + if ($(this).val() == "np"){ + $("#mapmethod_rqtl_geno").attr('disabled', 'disabled'); + $("#mapmethod_rqtl_geno").css('background-color', '#CCC'); + $("#missing_geno").attr('disabled', 'disabled'); + $("#missing_geno").css('background-color', '#CCC'); + } else { + $("#mapmethod_rqtl_geno").removeAttr('disabled'); + $("#mapmethod_rqtl_geno").css('background-color', '#FFF'); + $("#missing_geno").removeAttr('disabled'); + $("#missing_geno").css('background-color', '#FFF'); + } +}); + +$("#mapmethod_rqtl_geno").change(function() { + if ($(this).val() == "mr"){ + $("#missing_geno_div").css('display', 'block'); + } else { + $("#missing_geno_div").css('display', 'none'); + } +}); + +$("li.mapping_tab").click(function() { + if ($(this).hasClass("rqtl")){ + $(".rqtl_description").css("display", "block"); + } else { + $(".rqtl_description").css("display", "none"); + } +}); + +toggle_enable_disable = function(elem) { + return $(elem).prop("disabled", !$(elem).prop("disabled")); +}; + +$("#choose_closet_control").change(function() { + return toggle_enable_disable("#control_locus"); +}); + +$("#display_all_lrs").change(function() { + return toggle_enable_disable("#suggestive_lrs"); +}); -}).call(this); +$('#genofile_rqtl_geno').change(function() { + geno_location = $(this).children("option:selected").val().split(":")[0] + $('#scale_rqtl_geno').empty() + the_scales = js_data.scales_in_geno[geno_location] + for (var i = 0; i < the_scales.length; i++){ + $('#scale_rqtl_geno').append($("<option></option>").attr("value", the_scales[i][0]).text(the_scales[i][1])); + } +}); +$('#genofile_reaper').change(function() { + geno_location = $(this).children("option:selected").val().split(":")[0] + $('#scale_reaper').empty() + the_scales = js_data.scales_in_geno[geno_location] + for (var i = 0; i < the_scales.length; i++){ + $('#scale_reaper').append($("<option></option>").attr("value", the_scales[i][0]).text(the_scales[i][1])); + } +}); diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html index bc487a59..d1a97310 100644 --- a/wqflask/wqflask/templates/collections/view.html +++ b/wqflask/wqflask/templates/collections/view.html @@ -8,7 +8,7 @@ {% block content %} <!-- Start of body --> - <div class="container" style="min-width: 2050px;"> + <div class="container"> <h1> <span id="collection_name">{{ uc.name }}</span> <input type="text" name="new_collection_name" style="font-size: 20px; display: none; width: 500px;" class="form-control" placeholder="{{ uc.name }}"> @@ -85,7 +85,7 @@ <div style="margin-top: 10px; margin-bottom: 5px;"> <b>Show/Hide Columns:</b> </div> - <div> + <div style="min-width: 1500px;"> <table class="table-hover table-striped cell-border" id='trait_table' style="float: left;"> <thead> <tr> @@ -97,7 +97,7 @@ <th data-export="Description">Description</th> <th data-export="Location">Location</th> <th data-export="Mean">Mean</th> - <th data-export="Max LRS">Max LRS <a href="http://genenetwork.org//glossary.html#L" target="_blank"><sup style="font-size: small; color: #FF0000;"> ?</sup></a></th> + <th data-export="Max LRS">High P <a href="http://genenetwork.org//glossary.html#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="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="font-size: small; color: #FF0000;"> ?</sup></a></th> </tr> @@ -195,11 +195,11 @@ { 'type': "natural-minus-na", "width": 120 }, { "type": "natural" }, { "type": "natural" }, - { "type": "natural", "width": 130 }, - { "type": "natural", "width": 35 }, - { "type": "natural", "width": 35 }, - { "type": "natural", "width": 130 }, - { "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: [ diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index e2e1aa46..2318bfb8 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -140,7 +140,6 @@ <b>Show/Hide Columns:</b> </div> {% endif %} - <!--<div id="table_container" style="min-width: {% if dataset.type == 'ProbeSet' or dataset.type == 'Publish' %}2000{% else %}380{% endif %}px;">--> <div id="table_container" {% if dataset.type == 'ProbeSet' or dataset.type == 'Publish' %}style="min-width: 1500px;"{% endif %}> <table class="table-hover table-striped cell-border" id='trait_table' style="float: left; width: {% if dataset.type == 'Geno' %}380px{% else %}100%{% endif %};"> <tbody> @@ -290,7 +289,6 @@ { 'title': "Description", 'type': "natural", - 'width': "500px", 'data': null, 'render': function(data, type, row, meta) { try { @@ -303,7 +301,7 @@ { 'title': "Location", 'type': "natural-minus-na", - 'width': "120px", + 'width': "125px", 'data': "location" }, { @@ -314,23 +312,23 @@ 'orderSequence': [ "desc", "asc"] }, { - 'title': "Max LRS<a href=\"http://genenetwork.org//glossary.html#LRS\" target=\"_blank\" style=\"color: white;\"><sup style=\"font-size: small; color: #FF0000;\"> ?</sup></a>", + 'title': "High P<a href=\"http://genenetwork.org//glossary.html#LRS\" target=\"_blank\" style=\"color: white;\"><sup style=\"font-size: small; color: #FF0000;\"> ?</sup></a>", 'type': "natural-minus-na", 'data': "lrs_score", - 'width': "80px", + 'width': "60px", 'orderSequence': [ "desc", "asc"] }, { 'title': "Peak Location", 'type': "natural-minus-na", - 'width': "120px", + 'width': "125px", 'data': "lrs_location" }, { 'title': "Effect Size<a href=\"http://genenetwork.org//glossary.html#A\" target=\"_blank\" style=\"color: white;\"><sup style=\"font-size: small; color: #FF0000;\"> ?</sup></a>", 'type': "natural-minus-na", 'data': "additive", - 'width': "120px", + 'width': "85px", 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Publish' %}, { diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 56df2049..5ed7a90b 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -37,7 +37,7 @@ <input type="hidden" name="covariates" value=""> <input type="hidden" name="transform" value=""> - <div class="container" style="min-width: 1450px;"> + <div class="container" style="min-width: 700px;"> <div class="panel-group" id="accordion"> <div class="panel panel-default"> <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseOne" aria-expanded="true"> @@ -143,15 +143,18 @@ <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 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 language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> + <script type="text/javascript" src="https://cdn.datatables.net/scroller/2.0.2/js/dataTables.scroller.min.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/noUiSlider/nouislider.js"></script> - <script language="javascript" type="text/javascript" src="/static/new/javascript/get_covariates_from_collection.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" charset="utf-8"> @@ -208,162 +211,6 @@ } }); - //ZS: This variable is just created to get the column position of the first case attribute, since it's needed to set the row classes in createdRow for the DataTable - {% if sample_groups[0].attributes|length > 0 %} - {% if sample_groups[0].se_exists() %} - {% if has_num_cases %} - attribute_start_pos = 6 - {% else %} - attribute_start_pos = 5 - {% endif %} - {% else %} - {% if has_num_cases %} - attribute_start_pos = 4 - {% else %} - attribute_start_pos = 3 - {% endif %} - {% endif %} - {% endif %} - - var primary_table = $('#samples_primary').DataTable( { - 'initComplete': function(settings, json) { - $('.edit_sample_value').change(function() { - edit_data_change(); - }); - }, - 'createdRow': function ( row, data, index ) { - $(row).attr('id', "Primary_" + data.this_id) - $(row).addClass("value_se"); - if (data.outlier) { - $(row).addClass("outlier"); - } - $('td', row).eq(0).attr("align", "center"); - $('td', row).eq(0).attr("style", "padding: 2px 0px 0px 2px;"); - $('td', row).eq(1).addClass("column_name-Index") - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr("style", "padding: 2px 4px 0px 2px;"); - $('td', row).eq(2).addClass("column_name-Sample") - $('td', row).eq(3).addClass("column_name-Value") - $('td', row).eq(3).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% if sample_groups[0].se_exists() %} - $('td', row).eq(4).attr("align", "center"); - $('td', row).eq(4).attr("style", "padding-left: 2px; padding-right: 2px;"); - $('td', row).eq(5).addClass("column_name-SE") - $('td', row).eq(5).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% if has_num_cases %} - $('td', row).eq(6).addClass("column_name-num_cases") - $('td', row).eq(6).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% endif %} {% else %} {% if has_num_cases %} - $('td', row).eq(4).addClass("column_name-num_cases") - $('td', row).eq(4).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% endif %} {% endif %} - {% if sample_groups[0].attributes|length > 0 %} - {% for attribute in sample_groups[0].attributes|sort() %} - $('td', row).eq(attribute_start_pos + {{ loop.index }}).addClass("column_name-{{ sample_groups[0].attributes[attribute].name }}") - $('td', row).eq(attribute_start_pos + {{ loop.index }}).attr("style", "text-align: {{ sample_groups[0].attributes[attribute].alignment }}; padding-top: 2px; padding-bottom: 0px;") - {% endfor %} - {% endif %} - }, - 'data': js_data['sample_lists'][0], - 'columns': [ - { - 'data': null, - 'orderDataType': "dom-checkbox", - 'searchable' : false, - 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="">' - } - }, - { - 'title': "ID", - 'type': "natural", - 'searchable' : false, - 'data': "this_id" - }, - { - 'title': "Sample", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - return '<span class="edit_sample_sample_name">' + data.name + '</span>' - } - }, - { - 'title': "<div style='text-align: right;'>Value</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - 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=6 maxlength=6>' - } else { - return '<input type="text" data-value="' + data.value.toFixed(3) + '" data-qnorm="' + js_data['qnorm_values'][0][parseInt(data.this_id) - 1] + '" data-zscore="' + js_data['zscore_values'][0][parseInt(data.this_id) - 1] + '" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_value" value="' + data.value.toFixed(3) + '" size=6 maxlength=6>' - } - } - }{% if sample_groups[0].se_exists() %}, - { - 'bSortable': false, - 'type': "natural", - 'data': null, - 'searchable' : false, - 'render': function(data, type, row, meta) { - return '±' - } - }, - { - 'title': "<div style='text-align: right;'>SE</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.variance == 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_se" value="x" size=6 maxlength=6>' - } else { - return '<input type="text" data-value="' + data.variance.toFixed(3) + '" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_se" value="' + data.variance.toFixed(3) + '" size=6 maxlength=6>' - } - } - }{% endif %}{% if has_num_cases %}, - { - 'title': "<div style='text-align: right;'>N</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - 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 + '" style="text-align: right;" class="trait_value_input edit_sample_num_cases" value="x" size=4 maxlength=4>' - } else { - return '<input type="text" data-value="' + data.num_cases + '" data-qnorm="x" data-zscore="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_num_cases" value="' + data.num_cases + '" size=4 maxlength=4>' - } - } - }{% endif %}{% if sample_groups[0].attributes|length > 0 %}{% for attribute in sample_groups[0].attributes|sort() %}, - { - 'title': "<div style='text-align: {{ sample_groups[0].attributes[attribute].alignment }}'>{{ sample_groups[0].attributes[attribute].name }}</div>", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.extra_attributes['{{ sample_groups[0].attributes[attribute].name }}'] != null && data.extra_attributes['{{ sample_groups[0].attributes[attribute].name }}'] != undefined){ - return data.extra_attributes['{{ sample_groups[0].attributes[attribute].name }}'] - } else { - return "" - } - } - }{% endfor %}{% endif %} - ], - 'order': [[1, "asc"]], - 'sDom': "Ztr", - 'autoWidth': true, - 'deferRender': true, - 'paging': false, - 'orderClasses': true, - 'scrollY': "600px", - 'scrollCollapse': false, - 'processing': true, - 'language': { - 'loadingRecords': ' ', - 'processing': 'Loading...' - } - } ); - primary_table.on( 'order.dt search.dt draw.dt', function () { primary_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { cell.innerHTML = i+1; @@ -375,145 +222,6 @@ } ); {% if sample_groups|length != 1 %} - var other_table = $('#samples_other').DataTable( { - 'initComplete': function(settings, json) { - $('.edit_sample_value').change(function() { - edit_data_change(); - }); - }, - 'createdRow': function ( row, data, index ) { - $(row).attr('id', "Other_" + data.this_id) - $(row).addClass("value_se"); - if (data.outlier) { - $(row).addClass("outlier"); - } - $('td', row).eq(0).attr("align", "center"); - $('td', row).eq(0).attr("style", "padding: 2px 0px 0px 2px;"); - $('td', row).eq(1).addClass("column_name-Index") - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr("style", "padding: 2px 4px 0px 2px;"); - $('td', row).eq(2).addClass("column_name-Sample") - $('td', row).eq(3).addClass("column_name-Value") - $('td', row).eq(3).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% if sample_groups[1].se_exists() %} - $('td', row).eq(4).attr("align", "center"); - $('td', row).eq(4).attr("style", "padding-left: 2px; padding-right: 2px;"); - $('td', row).eq(5).addClass("column_name-SE") - $('td', row).eq(5).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% if has_num_cases %} - $('td', row).eq(6).addClass("column_name-num_cases") - $('td', row).eq(6).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% endif %} {% else %} {% if has_num_cases %} - $('td', row).eq(4).addClass("column_name-num_cases") - $('td', row).eq(4).attr("style", "text-align: right; padding-top: 2px; padding-bottom: 0px;"); - {% endif %} {% endif %} - {% if sample_groups[1].attributes|length > 0 %} - {% for attribute in sample_groups[1].attributes|sort() %} - $('td', row).eq(attribute_start_pos + {{ loop.index }}).addClass("column_name-{{ sample_groups[1].attributes[attribute].name }}") - $('td', row).eq(attribute_start_pos + {{ loop.index }}).attr("style", "text-align: {{ sample_groups[1].attributes[attribute].alignment }}; padding-top: 2px; padding-bottom: 0px;") - {% endfor %} - {% endif %} - }, - 'data': js_data['sample_lists'][1], - 'columns': [ - { - 'data': null, - 'orderDataType': "dom-checkbox", - 'searchable' : false, - 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="">' - } - }, - { - 'title': "ID", - 'type': "natural", - 'data': "this_id", - 'searchable' : false - }, - { - 'title': "Sample", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - return '<span class="edit_sample_sample_name">' + data.name + '</span>' - } - }, - { - 'title': "<div style='text-align: right;'>Value</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.value == null) { - return '<input type="text" data-value="x" data-qnorm="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_value" value="x" size=6 maxlength=6>' - } else { - return '<input type="text" data-value="' + data.value.toFixed(3) + '" data-qnorm="' + js_data['qnorm_values'][1][parseInt(data.this_id)] + '" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_value" value="' + data.value.toFixed(3) + '" size=6 maxlength=6>' - } - } - }{% if sample_groups[1].se_exists() %}, - { - 'bSortable': false, - 'type': "natural", - 'data': null, - 'searchable' : false, - 'render': function(data, type, row, meta) { - return '±' - } - }, - { - 'title': "<div style='text-align: right;'>SE</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.variance == null) { - return '<input type="text" data-value="x" data-qnorm="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_se" value="x" size=6 maxlength=6>' - } else { - return '<input type="text" data-value="' + data.variance.toFixed(3) + '" data-qnorm="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_se" value="' + data.variance.toFixed(3) + '" size=6 maxlength=6>' - } - } - }{% endif %}{% if has_num_cases %}, - { - 'title': "<div style='text-align: right;'>N</div>", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.num_cases == null) { - return '<input type="text" data-value="x" data-qnorm="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_num_cases" value="x" size=4 maxlength=4>' - } else { - return '<input type="text" data-value="' + data.num_cases + '" data-qnorm="x" name="value:' + data.name + '" style="text-align: right;" class="trait_value_input edit_sample_num_cases" value="' + data.num_cases + '" size=4 maxlength=4>' - } - } - }{% endif %}{% if sample_groups[1].attributes|length > 0 %}{% for attribute in sample_groups[1].attributes|sort() %}, - { - 'title': "<div style='text-align: {{ sample_groups[1].attributes[attribute].alignment }}'>{{ sample_groups[1].attributes[attribute].name }}</div>", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.extra_attributes['{{ sample_groups[1].attributes[attribute].name }}'] != null && data.extra_attributes['{{ sample_groups[1].attributes[attribute].name }}'] != undefined){ - return data.extra_attributes['{{ sample_groups[1].attributes[attribute].name }}'] - } else { - return "" - } - } - }{% endfor %}{% endif %} - ], - 'order': [[1, "asc"]], - 'sDom': "Ztr", - 'autoWidth': true, - 'deferRender': true, - 'paging': false, - 'orderClasses': true, - 'scrollY': "600px", - 'scrollCollapse': false, - 'processing': true, - 'language': { - 'loadingRecords': ' ', - 'processing': 'Loading...' - } - } ); - $('#other_searchbox').on( 'keyup', function () { other_table.search($(this).val()).draw(); } ); diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index 1378b91b..9420c9c6 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -1,5 +1,5 @@ <div> - <div class="col-xs-7"> + <div class="col-xs-6" style="min-width: 800px;"> <div style="padding: 20px" class="form-horizontal"> <div class="form-group"> @@ -39,7 +39,7 @@ <div class="form-group"> <label for="corr_return_results" class="col-xs-2 control-label">Return</label> - <div class="col-xs-3 controls"> + <div class="col-xs-4 controls"> <select name="corr_return_results" class="form-control"> {% for return_result in corr_tools.return_results_menu %} <option value="{{ return_result }}" @@ -55,7 +55,7 @@ <div class="form-group"> <label for="corr_samples_group" class="col-xs-2 control-label">Samples</label> - <div class="col-xs-3 controls"> + <div class="col-xs-4 controls"> <select name="corr_samples_group" class="form-control"> {% for group, pretty_group in sample_group_types.items() %} <option value="{{ group }}">{{ pretty_group }}</option> @@ -66,7 +66,7 @@ <div id="corr_sample_method" class="form-group"> <label for="corr_sample_method" class="col-xs-2 control-label">Type</label> - <div class="col-xs-3 controls"> + <div class="col-xs-4 controls"> <select name="corr_sample_method" class="form-control"> <option value="pearson">Pearson</option> <option value="spearman">Spearman Rank</option> @@ -77,7 +77,7 @@ {% if dataset.type != "Publish" %} <div class="form-group"> <label class="col-xs-2 control-label">Min Expr</label> - <div class="col-xs-3 controls"> + <div class="col-xs-4 controls"> <input name="min_expr" value="" type="text" class="form-control" style="width: 70px;"> </div> </div> @@ -114,7 +114,7 @@ </div> </div> </div> - <div class="col-xs-5"> + <div> <span id="sample_r_desc" class="correlation_desc fs12"> The <a href="http://genenetwork.org/correlationAnnotation.html#genetic_r">Sample Correlation</a> is computed diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index 27040045..94388b2f 100755 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -397,8 +397,8 @@ </div> </div> </div> - <div class="col-xs-7"> - <dl style="width: 500px;"> + <div> + <dl> {% for mapping_method in dataset.group.mapping_names %} {% if mapping_method == "GEMMA" %} <dt style="padding-top: 20px;">GEMMA</dt> diff --git a/wqflask/wqflask/templates/show_trait_transform_and_filter.html b/wqflask/wqflask/templates/show_trait_transform_and_filter.html index b4118b04..9fb560a0 100644 --- a/wqflask/wqflask/templates/show_trait_transform_and_filter.html +++ b/wqflask/wqflask/templates/show_trait_transform_and_filter.html @@ -1,83 +1,78 @@ <div> - <div class="form-horizontal"> - <p>Edit or delete values in the Trait Data boxes, and use the - <strong>Reset</strong> option as - needed. - </p> + <div class="form-horizontal"> + <p>Edit or delete values in the Trait Data boxes, and use the + <strong>Reset</strong> option as + needed. + </p> - <div id="blockMenuSpan" class="input-append" style="margin-bottom: 10px;"> - <label for="remove_samples_field">Block samples by index:</label> - <input type="text" id="remove_samples_field" placeholder="Example: 3, 5-10, 12"> - <select id="block_group" size="1"> - <option value="primary"> - {{ sample_group_types['samples_primary'] }} - </option> - <option value="other"> - {{ sample_group_types['samples_other'] }} - </option> - </select> - <input type="button" id="block_by_index" class="btn btn-danger" value="Block"> - </div> - <div id="remove_samples_invalid" class="alert alert-error" style="display:none;"> - Please check that your input is formatted correctly, e.g. <strong>3, 5-10, 12</strong> - </div> - {% if sample_groups[0].attributes %} - <div class="input-append" style="margin-top:10px; margin-bottom:10px;"> - <label for="exclude_menu">Block samples by group:</label> - <select id="exclude_menu" size=1> - {% for attribute in sample_groups[0].attributes %} - <option value="{{ sample_groups[0].attributes[attribute].name.replace(' ', '_') }}"> - {{ sample_groups[0].attributes[attribute].name }}</option> - {% endfor %} - </select> - <select id="attribute_values" size=1> - </select> - <input type="button" id="exclude_group" class="btn" value="Block"> - </div> - {% endif %} - <div> - <input type="button" id="hide_no_value" class="btn btn-default" value="Hide No Value"> - <input type="button" id="block_outliers" class="btn btn-default" value="Block Outliers"> - <input type="button" class="btn btn-success reset" value="Reset"> - <span class="input-append"> - <input type="button" class="btn btn-default export" value="Export"> - <select class="select optional span2 export_format"> - <option value="excel">Excel</option> - <option value="csv">CSV</option> - </select> - </span> - <br> - <div style="margin-top:10px;"> - <input type="button" id="normalize" class="btn btn-success" value="Normalize"> - <select id="norm_method" class="select optional span2"> - {% if negative_vals_exist == "false" %} - <option value="log2">Log2</option> - <option value="log10">Log10</option> - {% endif %} - <option value="zscore">Z-score</option> - <option value="qnorm">Quantile</option> - <option value="sqrt">Square Root</option> - <option value="invert">Invert +/-</option> + <div id="blockMenuSpan" class="input-append" style="margin-bottom: 10px;"> + <label for="remove_samples_field">Block samples by index:</label> + <input type="text" id="remove_samples_field" placeholder="Example: 3, 5-10, 12"> + <select id="block_group" size="1"> + <option value="primary"> + {{ sample_group_types['samples_primary'] }} + </option> + <option value="other"> + {{ sample_group_types['samples_other'] }} + </option> + </select> + <input type="button" id="block_by_index" class="btn btn-danger" value="Block"> + </div> + <div id="remove_samples_invalid" class="alert alert-error" style="display:none;"> + Please check that your input is formatted correctly, e.g. <strong>3, 5-10, 12</strong> + </div> + {% if sample_groups[0].attributes %} + <div class="input-append" style="margin-top:10px; margin-bottom:10px;"> + <label for="exclude_menu">Block samples by group:</label> + <select id="exclude_menu" size=1> + {% for attribute in sample_groups[0].attributes %} + <option value="{{ sample_groups[0].attributes[attribute].name.replace(' ', '_') }}"> + {{ sample_groups[0].attributes[attribute].name }}</option> + {% endfor %} + </select> + <select id="attribute_values" size=1> + </select> + <input type="button" id="exclude_group" class="btn" value="Block"> + </div> + {% endif %} + <div> + <input type="button" id="hide_no_value" class="btn btn-default" value="Hide No Value"> + <input type="button" id="block_outliers" class="btn btn-default" value="Block Outliers"> + <input type="button" class="btn btn-success reset" value="Reset"> + <span class="input-append"> + <input type="button" class="btn btn-default export" value="Export"> + <select class="select optional span2 export_format"> + <option value="excel">Excel</option> + <option value="csv">CSV</option> </select> - </div> - <!-- - {% if sample_groups[0].sample_qnorm is not none %} - <input type="button" id="qnorm" class="btn btn-default" value="Quantile Normalize"> + </span> + <br> + <div style="margin-top:10px;"> + <input type="button" id="normalize" class="btn btn-success" value="Normalize"> + <select id="norm_method" class="select optional span2"> + {% if negative_vals_exist == "false" %} + <option value="log2">Log2</option> + <option value="log10">Log10</option> + <option value="sqrt">Square Root</option> {% endif %} - --> + <option value="zscore">Z-score</option> + <option value="qnorm">Quantile</option> + <option value="invert">Invert +/-</option> + </select> </div> - <br> + </div> + <br> - <div> - <p>Outliers highlighted in - <strong style="background-color:orange;">orange</strong> - can be hidden using - the <strong>Hide Outliers</strong> button. - </p> + <div> + <p>Outliers highlighted in + <strong style="background-color:orange;">orange</strong> + can be hidden using + the <strong>Hide Outliers</strong> button. + </p> - <p>Samples with no value (x) can be hidden by clicking - <strong>Hide No Value</strong> button. - </p> - </div> - </div> + <p>Samples with no value (x) can be hidden by clicking + <strong>Hide No Value</strong> button. + </p> + </div> + </div> </div>
\ No newline at end of file diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 880a1cb2..70077703 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -1,5 +1,8 @@ -# WGCNA analysis for GN2 -# Author / Maintainer: Danny Arends <Danny.Arends@gmail.com> +""" +WGCNA analysis for GN2 + +Author / Maintainer: Danny Arends <Danny.Arends@gmail.com> +""" import sys from numpy import * import scipy as sp # SciPy @@ -17,106 +20,138 @@ from utility import helper_functions from rpy2.robjects.packages import importr utils = importr("utils") -## Get pointers to some common R functions -r_library = ro.r["library"] # Map the library function -r_options = ro.r["options"] # Map the options function -r_read_csv = ro.r["read.csv"] # Map the read.csv function -r_dim = ro.r["dim"] # Map the dim function -r_c = ro.r["c"] # Map the c function -r_cat = ro.r["cat"] # Map the cat function -r_paste = ro.r["paste"] # Map the paste function -r_unlist = ro.r["unlist"] # Map the unlist function -r_unique = ro.r["unique"] # Map the unique function -r_length = ro.r["length"] # Map the length function -r_unlist = ro.r["unlist"] # Map the unlist function -r_list = ro.r.list # Map the list function -r_matrix = ro.r.matrix # Map the matrix function -r_seq = ro.r["seq"] # Map the seq function -r_table = ro.r["table"] # Map the table function -r_names = ro.r["names"] # Map the names function -r_sink = ro.r["sink"] # Map the sink function -r_is_NA = ro.r["is.na"] # Map the is.na function -r_file = ro.r["file"] # Map the file function -r_png = ro.r["png"] # Map the png function for plotting -r_dev_off = ro.r["dev.off"] # Map the dev.off function +# Get pointers to some common R functions +r_library = ro.r["library"] # Map the library function +r_options = ro.r["options"] # Map the options function +r_read_csv = ro.r["read.csv"] # Map the read.csv function +r_dim = ro.r["dim"] # Map the dim function +r_c = ro.r["c"] # Map the c function +r_cat = ro.r["cat"] # Map the cat function +r_paste = ro.r["paste"] # Map the paste function +r_unlist = ro.r["unlist"] # Map the unlist function +r_unique = ro.r["unique"] # Map the unique function +r_length = ro.r["length"] # Map the length function +r_unlist = ro.r["unlist"] # Map the unlist function +r_list = ro.r.list # Map the list function +r_matrix = ro.r.matrix # Map the matrix function +r_seq = ro.r["seq"] # Map the seq function +r_table = ro.r["table"] # Map the table function +r_names = ro.r["names"] # Map the names function +r_sink = ro.r["sink"] # Map the sink function +r_is_NA = ro.r["is.na"] # Map the is.na function +r_file = ro.r["file"] # Map the file function +r_png = ro.r["png"] # Map the png function for plotting +r_dev_off = ro.r["dev.off"] # Map the dev.off function + class WGCNA(object): def __init__(self): + # To log output from stdout/stderr to a file add `r_sink(log)` print("Initialization of WGCNA") - #log = r_file("/tmp/genenetwork_wcgna.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") - r_library("WGCNA") # Load WGCNA - Should only be done once, since it is quite expensive - r_options(stringsAsFactors = False) + + # Load WGCNA - Should only be done once, since it is quite expensive + r_library("WGCNA") + r_options(stringsAsFactors=False) print("Initialization of WGCNA done, package loaded in R session") - self.r_enableWGCNAThreads = ro.r["enableWGCNAThreads"] # Map the enableWGCNAThreads function - self.r_pickSoftThreshold = ro.r["pickSoftThreshold"] # Map the pickSoftThreshold function - self.r_blockwiseModules = ro.r["blockwiseModules"] # Map the blockwiseModules function - self.r_labels2colors = ro.r["labels2colors"] # Map the labels2colors function - self.r_plotDendroAndColors = ro.r["plotDendroAndColors"] # Map the plotDendroAndColors function + # Map the enableWGCNAThreads function + self.r_enableWGCNAThreads = ro.r["enableWGCNAThreads"] + # Map the pickSoftThreshold function + self.r_pickSoftThreshold = ro.r["pickSoftThreshold"] + # Map the blockwiseModules function + self.r_blockwiseModules = ro.r["blockwiseModules"] + # Map the labels2colors function + self.r_labels2colors = ro.r["labels2colors"] + # Map the plotDendroAndColors function + self.r_plotDendroAndColors = ro.r["plotDendroAndColors"] print("Obtained pointers to WGCNA functions") def run_analysis(self, requestform): print("Starting WGCNA analysis on dataset") - self.r_enableWGCNAThreads() # Enable multi threading - self.trait_db_list = [trait.strip() for trait in requestform['trait_list'].split(',')] - print("Retrieved phenotype data from database", requestform['trait_list']) + # Enable multi threading + self.r_enableWGCNAThreads() + self.trait_db_list = [trait.strip() + for trait in requestform['trait_list'].split(',')] + print("Retrieved phenotype data from database", + requestform['trait_list']) helper_functions.get_trait_db_obs(self, self.trait_db_list) - self.input = {} # self.input contains the phenotype values we need to send to R - strains = [] # All the strains we have data for (contains duplicates) - traits = [] # All the traits we have data for (should not contain duplicates) + # self.input contains the phenotype values we need to send to R + self.input = {} + # All the strains we have data for (contains duplicates) + strains = [] + # All the traits we have data for (should not contain duplicates) + traits = [] for trait in self.trait_list: traits.append(trait[0].name) self.input[trait[0].name] = {} for strain in trait[0].data: strains.append(strain) - self.input[trait[0].name][strain] = trait[0].data[strain].value + self.input[trait[0].name][strain] = trait[0].data[strain].value # Transfer the load data from python to R - uStrainsR = r_unique(ro.Vector(strains)) # Unique strains in R vector + # Unique strains in R vector + uStrainsR = r_unique(ro.Vector(strains)) uTraitsR = r_unique(ro.Vector(traits)) # Unique traits in R vector r_cat("The number of unique strains:", r_length(uStrainsR), "\n") r_cat("The number of unique traits:", r_length(uTraitsR), "\n") - # rM is the datamatrix holding all the data in R /rows = strains columns = traits - rM = ro.r.matrix(ri.NA_Real, nrow=r_length(uStrainsR), ncol=r_length(uTraitsR), dimnames = r_list(uStrainsR, uTraitsR)) + # rM is the datamatrix holding all the data in + # R /rows = strains columns = traits + rM = ro.r.matrix(ri.NA_Real, nrow=r_length(uStrainsR), ncol=r_length( + uTraitsR), dimnames=r_list(uStrainsR, uTraitsR)) for t in uTraitsR: - trait = t[0] # R uses vectors every single element is a vector + # R uses vectors every single element is a vector + trait = t[0] for s in uStrainsR: - strain = s[0] # R uses vectors every single element is a vector - #DEBUG: print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) - rM.rx[strain, trait] = self.input[trait].get(strain) # Update the matrix location + # R uses vectors every single element is a vector + strain = s[0] + rM.rx[strain, trait] = self.input[trait].get( + strain) # Update the matrix location sys.stdout.flush() self.results = {} - self.results['nphe'] = r_length(uTraitsR)[0] # Number of phenotypes/traits - self.results['nstr'] = r_length(uStrainsR)[0] # Number of strains + # Number of phenotypes/traits + self.results['nphe'] = r_length(uTraitsR)[0] + self.results['nstr'] = r_length( + uStrainsR)[0] # Number of strains self.results['phenotypes'] = uTraitsR # Traits used - self.results['strains'] = uStrainsR # Strains used in the analysis - self.results['requestform'] = requestform # Store the user specified parameters for the output page + # Strains used in the analysis + self.results['strains'] = uStrainsR + # Store the user specified parameters for the output page + self.results['requestform'] = requestform - # Calculate soft threshold if the user specified the SoftThreshold variable + # Calculate soft threshold if the user specified the + # SoftThreshold variable if requestform.get('SoftThresholds') is not None: - powers = [int(threshold.strip()) for threshold in requestform['SoftThresholds'].rstrip().split(",")] - rpow = r_unlist(r_c(powers)) - print "SoftThresholds: {} == {}".format(powers, rpow) - self.sft = self.r_pickSoftThreshold(rM, powerVector = rpow, verbose = 5) - - print "PowerEstimate: {}".format(self.sft[0]) - self.results['PowerEstimate'] = self.sft[0] - if self.sft[0][0] is ri.NA_Integer: - print "No power is suitable for the analysis, just use 1" - self.results['Power'] = 1 # No power could be estimated - else: - self.results['Power'] = self.sft[0][0] # Use the estimated power + powers = [int(threshold.strip()) + for threshold in requestform['SoftThresholds'].rstrip().split(",")] + rpow = r_unlist(r_c(powers)) + print("SoftThresholds: {} == {}".format(powers, rpow)) + self.sft = self.r_pickSoftThreshold( + rM, powerVector=rpow, verbose=5) + + print("PowerEstimate: {}".format(self.sft[0])) + self.results['PowerEstimate'] = self.sft[0] + if self.sft[0][0] is ri.NA_Integer: + print "No power is suitable for the analysis, just use 1" + # No power could be estimated + self.results['Power'] = 1 + else: + # Use the estimated power + self.results['Power'] = self.sft[0][0] else: - # The user clicked a button, so no soft threshold selection - self.results['Power'] = requestform.get('Power') # Use the power value the user gives + # The user clicked a button, so no soft threshold selection + # Use the power value the user gives + self.results['Power'] = requestform.get('Power') # Create the block wise modules using WGCNA - network = self.r_blockwiseModules(rM, power = self.results['Power'], TOMType = requestform['TOMtype'], minModuleSize = requestform['MinModuleSize'], verbose = 3) + network = self.r_blockwiseModules( + rM, + power=self.results['Power'], + TOMType=requestform['TOMtype'], + minModuleSize=requestform['MinModuleSize'], + verbose=3) # Save the network for the GUI self.results['network'] = network @@ -130,7 +165,9 @@ class WGCNA(object): self.results['imgloc'] = GENERATED_IMAGE_DIR + self.results['imgurl'] r_png(self.results['imgloc'], width=1000, height=600, type='cairo-png') mergedColors = self.r_labels2colors(network[1]) - self.r_plotDendroAndColors(network[5][0], mergedColors, "Module colors", dendroLabels = False, hang = 0.03, addGuide = True, guideHang = 0.05) + self.r_plotDendroAndColors(network[5][0], mergedColors, + "Module colors", dendroLabels=False, + hang=0.03, addGuide=True, guideHang=0.05) r_dev_off() sys.stdout.flush() @@ -146,11 +183,9 @@ class WGCNA(object): print("Processing WGCNA output") template_vars = {} template_vars["input"] = self.input - template_vars["powers"] = self.sft[1:] # Results from the soft threshold analysis + # Results from the soft threshold analysis + template_vars["powers"] = self.sft[1:] template_vars["results"] = self.results self.render_image(results) sys.stdout.flush() - #r_sink(type = "message") # This restores R output to the stdout/stderr - #r_sink() # We should end the Rpy session more or less return(dict(template_vars)) - |