From 0b25ab1565faf3824d591c545dfe71dbd28c38ee Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Tue, 4 Apr 2017 18:23:57 +0000 Subject: Change scatterplot title font size --- wqflask/wqflask/static/new/javascript/scatterplot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/scatterplot.js b/wqflask/wqflask/static/new/javascript/scatterplot.js index de7b7906..d7f2a4a5 100644 --- a/wqflask/wqflask/static/new/javascript/scatterplot.js +++ b/wqflask/wqflask/static/new/javascript/scatterplot.js @@ -166,7 +166,7 @@ scatterplot = function() { maxx = xlim[1]; yticks = yticks != null ? yticks : ys.ticks(nyticks); xticks = xticks != null ? xticks : xs.ticks(nxticks); - titlegrp = g.append("g").attr("class", "title").append("text").attr("x", margin.left + width / 2).attr("y", margin.top - titlepos).style("fill", "black").style("font-size", "28px").text(title); + titlegrp = g.append("g").attr("class", "title").append("text").attr("x", margin.left + width / 2).attr("y", margin.top - titlepos).style("fill", "black").style("font-size", "24px").text(title); xaxis = g.append("g").attr("class", "x axis"); xaxis.selectAll("empty").data(xticks).enter().append("line").attr("x1", function(d) { return xscale(d); -- cgit v1.2.3 From 0408cc61181eaeda95bd1f60f76dc5798e315663 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 5 Apr 2017 15:37:29 +0000 Subject: - Temporary traits can be created, viewed, and added to collections - Correct PCA trait data is created but can't be saved yet - Added inner margins by increasing xDomain and yDomain of probability plot on trait page - Increased X/Y-axis label font size - Turned "processes" to 0 on runserver.py for PROD setting, since it doesn't work with threading - Improved appearance of correlation page table - Added links to github to index page - Removed js_data from GEMMA/PLINK mapping results, since it isn't used for those - Removed "Tissue" from trait page for phenotype traits --- wqflask/base/data_set.py | 35 +- wqflask/base/trait.py | 16 +- wqflask/base/webqtlConfig.py | 2 +- wqflask/runserver.py | 2 +- wqflask/wqflask/collect.py | 18 +- wqflask/wqflask/correlation/show_corr_results.py | 9 +- .../wqflask/correlation_matrix/show_corr_matrix.py | 87 +- wqflask/wqflask/marker_regression/gemma_mapping.py | 12 +- .../wqflask/marker_regression/marker_regression.py | 98 +- .../marker_regression/marker_regression_gn1.py | 63 +- wqflask/wqflask/marker_regression/plink_mapping.py | 35 +- wqflask/wqflask/show_trait/SampleList.py | 19 +- wqflask/wqflask/show_trait/show_trait.py | 174 +-- .../static/new/javascript/draw_probability_plot.js | 10 +- .../wqflask/static/new/javascript/show_trait.js | 2 +- wqflask/wqflask/static/new/packages/nvd3/nv.d3.css | 1188 ++++++++++---------- wqflask/wqflask/templates/correlation_page.html | 125 +- wqflask/wqflask/templates/index_page_orig.html | 12 +- .../wqflask/templates/marker_regression_gn1.html | 14 +- wqflask/wqflask/templates/show_trait.html | 4 +- wqflask/wqflask/templates/show_trait_details.html | 2 + .../templates/show_trait_mapping_tools.html | 7 +- wqflask/wqflask/templates/submit_trait.html | 2 +- wqflask/wqflask/views.py | 33 +- 24 files changed, 1081 insertions(+), 888 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 54dd3c4b..7f08135f 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -61,14 +61,17 @@ logger = getLogger(__name__ ) # Each subclass will add to this DS_NAME_MAP = {} -def create_dataset(dataset_name, dataset_type = None, get_samplelist = True): +def create_dataset(dataset_name, dataset_type = None, get_samplelist = True, group_name = None): if not dataset_type: dataset_type = Dataset_Getter(dataset_name) logger.debug("dataset_type", dataset_type) dataset_ob = DS_NAME_MAP[dataset_type] dataset_class = globals()[dataset_ob] - return dataset_class(dataset_name, get_samplelist) + if dataset_type == "Temp": + return dataset_class(dataset_name, get_samplelist, group_name) + else: + return dataset_class(dataset_name, get_samplelist) class Dataset_Types(object): @@ -261,10 +264,13 @@ class DatasetGroup(object): has multiple datasets associated with it. """ - def __init__(self, dataset): + def __init__(self, dataset, name=None): """This sets self.group and self.group_id""" #logger.debug("DATASET NAME2:", dataset.name) - self.name, self.id, self.genetic_type = fetchone(dataset.query_for_group) + if name == None: + self.name, self.id, self.genetic_type = fetchone(dataset.query_for_group) + else: + self.name, self.id, self.genetic_type = fetchone("SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType FROM InbredSet where Name='%s'" % name) if self.name == 'BXD300': self.name = "BXD" @@ -304,7 +310,7 @@ class DatasetGroup(object): elif mapping_id == "2": mapping_names = ["GEMMA"] elif mapping_id == "4": - mapping_names = ["PLINK"] + mapping_names = ["GEMMA", "PLINK"] else: mapping_names = [] @@ -319,9 +325,7 @@ class DatasetGroup(object): def check_plink_gemma(): if flat_file_exists("mapping"): MAPPING_PATH = flat_files("mapping")+"/" - if (os.path.isfile(MAPPING_PATH+self.name+".bed") and - (os.path.isfile(MAPPING_PATH+self.name+".map") or - os.path.isfile(MAPPING_PATH+self.name+".bim"))): + if os.path.isfile(MAPPING_PATH+self.name+".bed"): return True return False @@ -481,7 +485,7 @@ class DataSet(object): """ - def __init__(self, name, get_samplelist = True): + def __init__(self, name, get_samplelist = True, group_name = None): assert name, "Need a name" self.name = name @@ -493,11 +497,12 @@ class DataSet(object): self.setup() - self.check_confidentiality() - - self.retrieve_other_names() - - self.group = DatasetGroup(self) # sets self.group and self.group_id and gets genotype + if self.type == "Temp": #Need to supply group name as input if temp trait + self.group = DatasetGroup(self, group_name) # sets self.group and self.group_id and gets genotype + else: + self.check_confidentiality() + self.retrieve_other_names() + self.group = DatasetGroup(self) # sets self.group and self.group_id and gets genotype if get_samplelist == True: self.group.get_samplelist() self.species = species.TheSpecies(self) @@ -1156,6 +1161,8 @@ class MrnaAssayDataSet(DataSet): class TempDataSet(DataSet): '''Temporary user-generated data set''' + DS_NAME_MAP['Temp'] = 'TempDataSet' + def setup(self): self.search_fields = ['name', 'description'] diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index bf87e879..e22a51e4 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -62,6 +62,11 @@ class GeneralTrait(object): self.strand_probe = None self.symbol = None + self.LRS_score_repr = "N/A" + self.LRS_score_value = 0 + self.LRS_location_repr = "N/A" + self.LRS_location_value = 1000000 + if kw.get('fullname'): name2 = value.split("::") if len(name2) == 2: @@ -72,9 +77,10 @@ class GeneralTrait(object): # Todo: These two lines are necessary most of the time, but perhaps not all of the time # So we could add a simple if statement to short-circuit this if necessary - self = retrieve_trait_info(self, self.dataset, get_qtl_info=get_qtl_info) - if get_sample_info != False: - self = retrieve_sample_data(self, self.dataset) + if self.dataset.type != "Temp": + self = retrieve_trait_info(self, self.dataset, get_qtl_info=get_qtl_info) + if get_sample_info != False: + self = retrieve_sample_data(self, self.dataset) def get_name(self): @@ -315,12 +321,12 @@ def get_sample_data(): # #return jsonable_sample_data -def jsonable(trait, dataset_name): +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) + 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, diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py index e5f10edf..1e47e183 100644 --- a/wqflask/base/webqtlConfig.py +++ b/wqflask/base/webqtlConfig.py @@ -65,7 +65,7 @@ ENSEMBLETRANSCRIPT_URL="http://useast.ensembl.org/Mus_musculus/Lucene/Details?sp # want to reach this base dir assert_writable_dir(TEMPDIR) -TMPDIR = mk_dir(TEMPDIR+'/gn2/') +TMPDIR = mk_dir(TEMPDIR+'gn2') assert_writable_dir(TMPDIR) CACHEDIR = mk_dir(TMPDIR+'/cache/') diff --git a/wqflask/runserver.py b/wqflask/runserver.py index 0342b7ad..a6ae28af 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -50,5 +50,5 @@ else: # staging/production modes debug=False, use_debugger=False, threaded=True, - processes=8, + processes=0, use_reloader=True) diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index ba555094..478dbcaa 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -203,7 +203,8 @@ def process_traits(unprocessed_traits): data, _separator, hmac = trait.rpartition(':') data = data.strip() assert hmac==user_manager.actual_hmac_creation(data), "Data tampering?" - traits.add (str(data)) + traits.add(str(data)) + return traits def report_change(len_before, len_now): @@ -244,7 +245,6 @@ def collections_new(): if "sign_in" in params: return redirect(url_for('login')) - if "create_new" in params: print("in create_new") collection_name = params['new_collection'] @@ -376,13 +376,17 @@ def view_collection(): for atrait in traits: name, dataset_name = atrait.split(':') - dataset = create_dataset(dataset_name) - - trait_ob = trait.GeneralTrait(name=name, dataset=dataset) - trait_ob = trait.retrieve_trait_info(trait_ob, dataset, get_qtl_info=True) + if dataset_name == "Temp": + group = name.split("_")[2] + dataset = create_dataset(dataset_name, dataset_type = "Temp", group_name = group) + trait_ob = trait.GeneralTrait(name=name, dataset=dataset) + else: + dataset = create_dataset(dataset_name) + trait_ob = trait.GeneralTrait(name=name, dataset=dataset) + trait_ob = trait.retrieve_trait_info(trait_ob, dataset, get_qtl_info=True) trait_obs.append(trait_ob) - json_version.append(trait.jsonable(trait_ob, dataset_name)) + json_version.append(trait.jsonable(trait_ob)) if "uc_id" in params: collection_info = dict(trait_obs=trait_obs, diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index cc21d1bf..7957e643 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -96,7 +96,14 @@ class CorrelationResults(object): print("TESTING...") with Bench("Doing correlations"): - helper_functions.get_species_dataset_trait(self, start_vars) + if start_vars['dataset'] == "Temp": + self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = start_vars['group']) + self.trait_id = "Temp" + self.this_trait = GeneralTrait(dataset=self.dataset, + name=self.trait_id, + cellid=None) + else: + helper_functions.get_species_dataset_trait(self, start_vars) self.dataset.group.read_genotype_file() diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 630980c7..95a5f6a6 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -33,6 +33,9 @@ import math import collections import resource +import numarray +import numarray.linear_algebra as la +import numpy as np import scipy from rpy2.robjects.packages import importr @@ -91,31 +94,40 @@ class CorrelationMatrix(object): this_trait_vals.append('') self.sample_data.append(this_trait_vals) + if len(this_trait_vals) < len(self.trait_list): #Shouldn't do PCA if there are more traits than observations/samples + return False + self.lowest_overlap = 8 #ZS: Variable set to the lowest overlapping samples in order to notify user, or 8, whichever is lower (since 8 is when we want to display warning) self.corr_results = [] self.pca_corr_results = [] + self.trait_data_array = [] for trait_db in self.trait_list: this_trait = trait_db[0] this_db = trait_db[1] - this_db_samples = this_db.group.samplelist + this_db_samples = this_db.group.all_samples_ordered() this_sample_data = this_trait.data + this_trait_vals = [] + for index, sample in enumerate(this_db_samples): + if (sample in this_sample_data): + sample_value = this_sample_data[sample].value + this_trait_vals.append(sample_value) + self.trait_data_array.append(this_trait_vals) + corr_result_row = [] pca_corr_result_row = [] is_spearman = False #ZS: To determine if it's above or below the diagonal for target in self.trait_list: target_trait = target[0] target_db = target[1] - target_samples = target_db.group.samplelist - + target_samples = target_db.group.all_samples_ordered() target_sample_data = target_trait.data this_trait_vals = [] target_vals = [] for index, sample in enumerate(target_samples): - if (sample in this_sample_data) and (sample in target_sample_data): sample_value = this_sample_data[sample].value target_sample_value = target_sample_data[sample].value @@ -144,13 +156,14 @@ class CorrelationMatrix(object): self.corr_results.append(corr_result_row) self.pca_corr_results.append(pca_corr_result_row) - print("corr_results:", pf(self.corr_results)) + corr_result_eigen = la.eigenvectors(numarray.array(self.pca_corr_results)) + corr_eigen_value, corr_eigen_vectors = sortEigenVectors(corr_result_eigen) groups = [] for sample in self.all_sample_list: groups.append(1) - pca = self.calculate_pca(self.pca_corr_results, range(len(self.traits))) + pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors) self.loadings_array = self.process_loadings() @@ -180,31 +193,34 @@ class CorrelationMatrix(object): #print("trait_list:", self.trait_list) - def calculate_pca(self, corr_results, cols): + def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors): base = importr('base') stats = importr('stats') - print("checking:", pf(stats.rnorm(100))) - corr_results_to_list = robjects.FloatVector([item for sublist in corr_results for item in sublist]) - print("corr_results:", pf(corr_results_to_list)) + corr_results_to_list = robjects.FloatVector([item for sublist in self.pca_corr_results for item in sublist]) m = robjects.r.matrix(corr_results_to_list, nrow=len(cols)) eigen = base.eigen(m) - print("eigen:", eigen) pca = stats.princomp(m, cor = "TRUE") - print("pca:", pca) self.loadings = pca.rx('loadings') self.scores = pca.rx('scores') self.scale = pca.rx('scale') - print("scores:", pca.rx('scores')) - print("scale:", pca.rx('scale')) + trait_array = zScore(self.trait_data_array) + trait_array = np.array(trait_array) + trait_array_vectors = np.dot(corr_eigen_vectors, trait_array) + + pca_traits = [] + for i, vector in enumerate(trait_array_vectors): + if corr_eigen_value[i-1] < 100.0/len(self.trait_list): + pca_traits.append(vector*-1.0) + + print("pca_traits:", pca_traits) return pca def process_loadings(self): loadings_array = [] loadings_row = [] - print("before loop:", self.loadings[0]) for i in range(len(self.trait_list)): loadings_row = [] if len(self.trait_list) > 2: @@ -215,6 +231,45 @@ class CorrelationMatrix(object): position = i + len(self.trait_list)*j loadings_row.append(self.loadings[0][position]) loadings_array.append(loadings_row) - print("loadings:", loadings_array) return loadings_array +def zScore(trait_data_array): + NN = len(trait_data_array[0]) + if NN < 10: + return trait_data_array + else: + i = 0 + for data in trait_data_array: + N = len(data) + S = reduce(lambda x,y: x+y, data, 0.) + SS = reduce(lambda x,y: x+y*y, data, 0.) + mean = S/N + var = SS - S*S/N + stdev = math.sqrt(var/(N-1)) + if stdev == 0: + stdev = 1e-100 + data2 = map(lambda x:(x-mean)/stdev,data) + trait_data_array[i] = data2 + i += 1 + return trait_data_array + +def sortEigenVectors(vector): + try: + eigenValues = vector[0].tolist() + eigenVectors = vector[1].tolist() + combines = [] + i = 0 + for item in eigenValues: + combines.append([eigenValues[i],eigenVectors[i]]) + i += 1 + combines.sort(webqtlUtil.cmpEigenValue) + A = [] + B = [] + for item in combines: + A.append(item[0]) + B.append(item[1]) + sum = reduce(lambda x,y: x+y, A, 0.0) + A = map(lambda x:x*100.0/sum, A) + return [A,B] + except: + return [] \ No newline at end of file diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 3bde61cd..6e2cb972 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -1,22 +1,22 @@ import os, math from base import webqtlConfig -from utility.tools import flat_files, GEMMA_COMMAND, GEMMA_RESULTS_PATH +from utility.tools import flat_files, GEMMA_COMMAND def run_gemma(this_dataset, samples, vals): """Generates p-values for each marker using GEMMA""" print("INSIDE GEMMA_MAPPING") - gen_pheno_txt_file(this_dataset, samples, vals) + gen_pheno_txt_file(this_dataset, vals) # use GEMMA_RUN in the next one, create a unique temp file - gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.sXX.txt -lmm 1 -outdir %s/output -o %s_output' % (flat_files('mapping'), + gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -outdir %s -o %s_output' % (flat_files('mapping'), this_dataset.group.name, flat_files('mapping'), this_dataset.group.name, - GEMMA_RESULTS_PATH, + webqtlConfig.GENERATED_IMAGE_DIR, this_dataset.group.name) print("gemma_command:" + gemma_command) @@ -26,7 +26,7 @@ def run_gemma(this_dataset, samples, vals): return marker_obs -def gen_pheno_txt_file(this_dataset, samples, vals): +def gen_pheno_txt_file(this_dataset, vals): """Generates phenotype file for GEMMA""" current_file_data = [] @@ -47,7 +47,7 @@ def parse_gemma_output(this_dataset): included_markers = [] p_values = [] marker_obs = [] - with open("{}/output/{}_output.assoc.txt".format(GEMMA_RESULTS_PATH, this_dataset.group.name)) as output_file: + with open("{}{}_output.assoc.txt".format(webqtlConfig.GENERATED_IMAGE_DIR, this_dataset.group.name)) as output_file: for line in output_file: if line.startswith("chr"): continue diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index b1d2f811..87532445 100644 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -211,6 +211,8 @@ class MarkerRegression(object): self.control_marker, self.manhattan_plot) elif self.mapping_method == "plink": + self.score_type = "-log(p)" + self.manhattan_plot = True results = plink_mapping.run_plink(self.this_trait, self.dataset, self.species, self.vals, self.maf) #results = self.run_plink() elif self.mapping_method == "pylmm": @@ -263,52 +265,53 @@ class MarkerRegression(object): self.trimmed_markers = trim_markers_for_table(results) - self.json_data['chr'] = [] - self.json_data['pos'] = [] - self.json_data['lod.hk'] = [] - self.json_data['markernames'] = [] - - self.json_data['suggestive'] = self.suggestive - self.json_data['significant'] = self.significant - - #Need to convert the QTL objects that qtl reaper returns into a json serializable dictionary - for index, qtl in enumerate(self.qtl_results): - #if index<40: - # logger.debug("lod score is:", qtl['lod_score']) - if qtl['chr'] == highest_chr and highest_chr != "X" and highest_chr != "X/Y": - #logger.debug("changing to X") - self.json_data['chr'].append("X") - else: - self.json_data['chr'].append(str(qtl['chr'])) - self.json_data['pos'].append(qtl['Mb']) - if 'lrs_value' in qtl.keys(): - self.json_data['lod.hk'].append(str(qtl['lrs_value'])) - else: - self.json_data['lod.hk'].append(str(qtl['lod_score'])) - self.json_data['markernames'].append(qtl['name']) - - #Get chromosome lengths for drawing the interval map plot - chromosome_mb_lengths = {} - self.json_data['chrnames'] = [] - for key in self.species.chromosomes.chromosomes.keys(): - self.json_data['chrnames'].append([self.species.chromosomes.chromosomes[key].name, self.species.chromosomes.chromosomes[key].mb_length]) - chromosome_mb_lengths[key] = self.species.chromosomes.chromosomes[key].mb_length - - # logger.debug("json_data:", self.json_data) - - self.js_data = dict( - result_score_type = self.score_type, - json_data = self.json_data, - this_trait = self.this_trait.name, - data_set = self.dataset.name, - maf = self.maf, - manhattan_plot = self.manhattan_plot, - mapping_scale = self.mapping_scale, - chromosomes = chromosome_mb_lengths, - qtl_results = self.qtl_results, - num_perm = self.num_perm, - perm_results = self.perm_output, - ) + if self.mapping_method != "gemma": + self.json_data['chr'] = [] + self.json_data['pos'] = [] + self.json_data['lod.hk'] = [] + self.json_data['markernames'] = [] + + self.json_data['suggestive'] = self.suggestive + self.json_data['significant'] = self.significant + + #Need to convert the QTL objects that qtl reaper returns into a json serializable dictionary + for index, qtl in enumerate(self.qtl_results): + #if index<40: + # logger.debug("lod score is:", qtl['lod_score']) + if qtl['chr'] == highest_chr and highest_chr != "X" and highest_chr != "X/Y": + #logger.debug("changing to X") + self.json_data['chr'].append("X") + else: + self.json_data['chr'].append(str(qtl['chr'])) + self.json_data['pos'].append(qtl['Mb']) + if 'lrs_value' in qtl.keys(): + self.json_data['lod.hk'].append(str(qtl['lrs_value'])) + else: + self.json_data['lod.hk'].append(str(qtl['lod_score'])) + self.json_data['markernames'].append(qtl['name']) + + #Get chromosome lengths for drawing the interval map plot + chromosome_mb_lengths = {} + self.json_data['chrnames'] = [] + for key in self.species.chromosomes.chromosomes.keys(): + self.json_data['chrnames'].append([self.species.chromosomes.chromosomes[key].name, self.species.chromosomes.chromosomes[key].mb_length]) + chromosome_mb_lengths[key] = self.species.chromosomes.chromosomes[key].mb_length + + # logger.debug("json_data:", self.json_data) + + self.js_data = dict( + result_score_type = self.score_type, + json_data = self.json_data, + this_trait = self.this_trait.name, + data_set = self.dataset.name, + maf = self.maf, + manhattan_plot = self.manhattan_plot, + mapping_scale = self.mapping_scale, + chromosomes = chromosome_mb_lengths, + qtl_results = self.qtl_results, + num_perm = self.num_perm, + perm_results = self.perm_output, + ) def run_rqtl_plink(self): # os.chdir("") never do this inside a webserver!! @@ -599,8 +602,7 @@ def trim_markers_for_table(markers): #ZS: So we end up with a list of just 200 markers if len(sorted_markers) >= 200: - trimming_factor = 200 / len(sorted_markers) - trimmed_sorted_markers = sorted_markers[:int(len(sorted_markers) * trimming_factor)] + trimmed_sorted_markers = sorted_markers[:200] return trimmed_sorted_markers else: return sorted_markers diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index 392ad745..49959a74 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -181,7 +181,8 @@ class MarkerRegression(object): self.mapmodel_rqtl_geno = start_vars['model'] self.pair_scan = start_vars['pair_scan'] - self.js_data = start_vars['js_data'] + if self.mapping_method != "gemma" and self.mapping_method != "plink": + self.js_data = start_vars['js_data'] self.trimmed_markers = start_vars['trimmed_markers'] #Top markers to display in table #ZS: Think I can just get all this from dataset object now @@ -564,7 +565,6 @@ class MarkerRegression(object): gifmap = self.plotIntMapping(intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= showLocusForm) self.gifmap = gifmap.__str__() - #print("GIFMAP:", gifmap.__str__()) self.filename= webqtlUtil.genRandStr("Itvl_") intCanvas.save(os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename), format='jpeg') @@ -847,8 +847,7 @@ class MarkerRegression(object): pass #draw position, no need to use a separate function - if self.genotype.Mbmap: - self.drawProbeSetPosition(canvas, plotXScale, offset=newoffset, zoom = zoom) + self.drawProbeSetPosition(canvas, plotXScale, offset=newoffset, zoom = zoom) return gifmap @@ -1010,35 +1009,34 @@ class MarkerRegression(object): locPixel = xLeftOffset + (Mb-self.startMb)*plotXScale else: locPixel = xLeftOffset - for i, _chr in enumerate(self.genotype): - if _chr.name != Chr: - locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + for i, _chr in enumerate(self.ChrList[1:]): + if _chr[0] != Chr: + locPixel += (self.ChrLengthDistList[i-1] + self.GraphInterval)*plotXScale else: locPixel += Mb*plotXScale break else: if self.selectedChr > -1: - if self.genotype[0].name != Chr: - return - else: - for i, _locus in enumerate(self.genotype[0]): - #the trait's position is on the left of the first genotype - if i==0 and _locus.Mb >= Mb: - locPixel=-1 - break + for i, qtlresult in enumerate(self.qtlresults): + if qtlresult['Chr'] != self.selectedChr: + continue - #the trait's position is between two traits - if i > 0 and self.genotype[0][i-1].Mb < Mb and _locus.Mb >= Mb: - locPixel = xLeftOffset + plotXScale*(self.genotype[0][i-1].cM+(_locus.cM-self.genotype[0][i-1].cM)*(Mb -self.genotype[0][i-1].Mb)/(_locus.Mb-self.genotype[0][i-1].Mb)) - break + if i==0 and qtlresult['Mb'] >= Mb: + locPixel=-1 + break + + #the trait's position is between two traits + if i > 0 and self.qtlresults[i-1]['Mb'] < Mb and qtlresult['Mb'] >= Mb: + locPixel = xLeftOffset + plotXScale*(self.qtlresults[i-1]['cM']+(qtlresult['cM']-self.qtlresults[i-1]['cM'])*(Mb - self.qtlresults[i-1]['Mb'])/(qtlresult['Mb']-self.qtlresults[i-1]['Mb'])) + break - #the trait's position is on the right of the last genotype - if i==len(self.genotype[0]) and Mb>=_locus.Mb: - locPixel = -1 + #the trait's position is on the right of the last genotype + if i==len(self.qtlresults) and Mb>=qtlresult['Mb']: + locPixel = -1 else: locPixel = xLeftOffset - for i, _chr in enumerate(self.genotype): - if _chr.name != Chr: + for i, _chr in enumerate(self.ChrList): + if _chr != Chr: locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale else: locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale @@ -1190,13 +1188,16 @@ class MarkerRegression(object): else: if self.mapping_method == "gemma": string2 = 'Using GEMMA mapping method with no control for other QTLs.' + elif self.mapping_method == "plink": + string2 = 'Using PLINK mapping method with no control for other QTLs.' else: string2 = 'Using Haldane mapping function with no control for other QTLs' - d = 4+ max(canvas.stringWidth(string1,font=labelFont),canvas.stringWidth(string2,font=labelFont)) if self.this_trait.name: identification = "Trait ID: %s : %s" % (self.dataset.fullname, self.this_trait.name) + d = 4+ max(canvas.stringWidth(identification, font=labelFont), canvas.stringWidth(string1, font=labelFont), canvas.stringWidth(string2, font=labelFont)) canvas.drawString(identification,canvas.size[0] - xRightOffset-d,20*fontZoom,font=labelFont,color=labelColor) - + else: + d = 4+ max(canvas.stringWidth(string1, font=labelFont), canvas.stringWidth(string2, font=labelFont)) canvas.drawString(string1,canvas.size[0] - xRightOffset-d,35*fontZoom,font=labelFont,color=labelColor) canvas.drawString(string2,canvas.size[0] - xRightOffset-d,50*fontZoom,font=labelFont,color=labelColor) @@ -1915,7 +1916,7 @@ class MarkerRegression(object): if self.lrsMax <= 0: #sliding scale if "lrs_value" in self.qtlresults[0]: LRS_LOD_Max = max([result['lrs_value'] for result in self.qtlresults]) - if self.LRS_LOD == "LOD": + if self.LRS_LOD == "LOD" or self.LRS_LOD == "-log(p)": LRS_LOD_Max = LRS_LOD_Max / self.LODFACTOR if self.permChecked and self.nperm > 0 and not self.multipleInterval: self.significant = min(self.significant / self.LODFACTOR, webqtlConfig.MAXLRS) @@ -2118,7 +2119,7 @@ class MarkerRegression(object): # fix the over limit LRS graph issue since genotype trait may give infinite LRS; # for any lrs is over than 460(LRS max in this system), it will be reset to 460 if 'lrs_value' in qtlresult: - if self.LRS_LOD == "LOD": + if self.LRS_LOD == "LOD" or self.LRS_LOD == "-log(p)": if qtlresult['lrs_value'] > 460 or qtlresult['lrs_value']=='inf': Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/(LRS_LOD_Max*self.LODFACTOR) else: @@ -2143,7 +2144,11 @@ class MarkerRegression(object): # Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/LRS_LOD_Max if self.manhattan_plot == True: - canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont) + if previous_chr_as_int % 2 == 1: + point_color = pid.grey + else: + point_color = pid.black + canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=point_color, font=symbolFont) else: LRSCoordXY.append((Xc, Yc)) diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index b457b9a0..3d31da1a 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -3,7 +3,7 @@ import os from base.webqtlConfig import TMPDIR from utility import webqtlUtil -from utility.tools import PLINK_COMMAND +from utility.tools import flat_files, PLINK_COMMAND import utility.logger logger = utility.logger.getLogger(__name__ ) @@ -11,12 +11,11 @@ logger = utility.logger.getLogger(__name__ ) def run_plink(this_trait, dataset, species, vals, maf): plink_output_filename = webqtlUtil.genRandStr("%s_%s_"%(dataset.group.name, this_trait.name)) - gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = plink_output_filename) + gen_pheno_txt_file(dataset, vals) + #gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = plink_output_filename) - plink_command = PLINK_COMMAND + ' --noweb --ped %s/%s.ped --no-fid --no-parents --no-sex --no-pheno --map %s/%s.map --pheno %s%s.txt --pheno-name %s --maf %s --missing-phenotype -9999 --out %s%s --assoc ' % ( - PLINK_PATH, dataset.group.name, PLINK_PATH, dataset.group.name, - TMPDIR, plink_output_filename, this_trait.name, maf, TMPDIR, - plink_output_filename) + plink_command = PLINK_COMMAND + ' --noweb --bfile %s/%s --no-fid --no-parents --no-sex --maf %s --missing-phenotype -9 --out %s/%s --assoc ' % ( + flat_files('mapping'), dataset.group.name, maf, TMPDIR, plink_output_filename) logger.debug("plink_command:", plink_command) os.system(plink_command) @@ -29,11 +28,27 @@ def run_plink(this_trait, dataset, species, vals, maf): # self.dataset.group.markers.markers.remove(marker) # #del self.dataset.group.markers.markers[marker] - logger.debug("p_values:", pf(p_values)) + logger.debug("p_values:", p_values) dataset.group.markers.add_pvalues(p_values) return dataset.group.markers.markers +def gen_pheno_txt_file(this_dataset, vals): + """Generates phenotype file for GEMMA/PLINK""" + + current_file_data = [] + with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "r") as outfile: + for i, line in enumerate(outfile): + split_line = line.split() + current_file_data.append(split_line) + + with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "w") as outfile: + for i, line in enumerate(current_file_data): + if vals[i] == "x": + this_val = -9 + else: + this_val = vals[i] + outfile.write(line[1] + " " + line[1] + " " + line[2] + " " + line[3] + " " + line[4] + " " + str(this_val) + "\n") def gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = ''): ped_sample_list = get_samples_from_ped_file(dataset) @@ -71,7 +86,7 @@ def gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = ''): # get strain name from ped file in order def get_samples_from_ped_file(dataset): - ped_file= open("{}/{}.ped".format(PLINK_PATH, dataset.group.name),"r") + ped_file= open("{}{}.ped".format(flat_files('mapping'), dataset.group.name),"r") line = ped_file.readline() sample_list=[] @@ -89,9 +104,9 @@ def get_samples_from_ped_file(dataset): def parse_plink_output(output_filename, species): plink_results={} - threshold_p_value = 0.01 + threshold_p_value = 1 - result_fp = open("%s%s.qassoc"% (TMPDIR, output_filename), "rb") + result_fp = open("%s/%s.qassoc"% (TMPDIR, output_filename), "rb") header_line = result_fp.readline()# read header line line = result_fp.readline() diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 7e7503d4..6d84a960 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -32,7 +32,6 @@ class SampleList(object): self.sample_attribute_values = {} self.get_attributes() - # logger.debug("camera: attributes are:", pf(self.attributes)) if self.this_trait and self.dataset and self.dataset.type == 'ProbeSet': self.get_extra_attribute_values() @@ -40,12 +39,18 @@ class SampleList(object): for counter, sample_name in enumerate(sample_names, 1): sample_name = sample_name.replace("_2nd_", "") - #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(sample_name) + 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 self.this_trait[counter-1] != '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) + 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) #sampleNameAdd = '' #if fd.RISet == 'AXBXA' and sampleName in ('AXB18/19/20','AXB13/14','BXA8/17'): diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 5d55ebe1..b2dfc4ac 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, print_function, division import string import os +import datetime import cPickle import uuid import json as json @@ -9,6 +10,9 @@ import json as json from collections import OrderedDict +import redis +Redis = redis.StrictRedis() + from flask import Flask, g from htmlgen import HTMLgen2 as HT @@ -42,16 +46,33 @@ class ShowTrait(object): def __init__(self, kw): logger.debug("in ShowTrait, kw are:", kw) - if kw['trait_id'] != None: + if 'trait_id' in kw and kw['dataset'] != "Temp": self.temp_trait = False self.trait_id = kw['trait_id'] helper_functions.get_species_dataset_trait(self, kw) - else: + elif 'group' in kw: self.temp_trait = True - self.trait_vals = kw['trait_paste'].split() - self.temp_group = kw['group'] + self.trait_id = "Temp_"+kw['species']+ "_" + kw['group'] + "_" + datetime.datetime.now().strftime("%m%d%H%M%S") self.temp_species = kw['species'] - #self.create_temp_trait() + self.temp_group = kw['group'] + self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = self.temp_group) + self.this_trait = GeneralTrait(dataset=self.dataset, + name=self.trait_id, + cellid=None) + self.trait_vals = kw['trait_paste'].split() + + # Put values in Redis so they can be looked up later if added to a collection + Redis.set(self.trait_id, kw['trait_paste']) + else: + self.temp_trait = True + self.trait_id = kw['trait_id'] + self.temp_species = self.trait_id.split("_")[1] + self.temp_group = self.trait_id.split("_")[2] + self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = self.temp_group) + self.this_trait = GeneralTrait(dataset=self.dataset, + name=self.trait_id, + cellid=None) + self.trait_vals = Redis.get(self.trait_id).split() #self.dataset.group.read_genotype_file() @@ -64,17 +85,17 @@ class ShowTrait(object): self.build_correlation_tools() #Get nearest marker for composite mapping + if not self.temp_trait: + if hasattr(self.this_trait, 'locus_chr') and self.this_trait.locus_chr != "" and self.dataset.type != "Geno" and self.dataset.type != "Publish": + self.nearest_marker = get_nearest_marker(self.this_trait, self.dataset) + #self.nearest_marker1 = get_nearest_marker(self.this_trait, self.dataset)[0] + #self.nearest_marker2 = get_nearest_marker(self.this_trait, self.dataset)[1] + else: + self.nearest_marker = "" + #self.nearest_marker1 = "" + #self.nearest_marker2 = "" - if hasattr(self.this_trait, 'locus_chr') and self.this_trait.locus_chr != "" and self.dataset.type != "Geno" and self.dataset.type != "Publish": - self.nearest_marker = get_nearest_marker(self.this_trait, self.dataset) - #self.nearest_marker1 = get_nearest_marker(self.this_trait, self.dataset)[0] - #self.nearest_marker2 = get_nearest_marker(self.this_trait, self.dataset)[1] - else: - self.nearest_marker = "" - #self.nearest_marker1 = "" - #self.nearest_marker2 = "" - - self.make_sample_lists(self.this_trait) + self.make_sample_lists() # Todo: Add back in the ones we actually need from below, as we discover we need them hddn = OrderedDict() @@ -84,17 +105,22 @@ class ShowTrait(object): hddn['trait_id'] = self.trait_id hddn['dataset'] = self.dataset.name + hddn['temp_trait'] = False + if self.temp_trait: + hddn['temp_trait'] = True + hddn['group'] = self.temp_group + hddn['species'] = self.temp_species hddn['use_outliers'] = False hddn['method'] = "pylmm" hddn['mapping_display_all'] = True hddn['suggestive'] = 0 hddn['num_perm'] = 0 hddn['manhattan_plot'] = "" - if hasattr(self.this_trait, 'locus_chr') and self.this_trait.locus_chr != "" and self.dataset.type != "Geno" and self.dataset.type != "Publish": - hddn['control_marker'] = self.nearest_marker - #hddn['control_marker'] = self.nearest_marker1+","+self.nearest_marker2 - else: - hddn['control_marker'] = "" + hddn['control_marker'] = "" + if not self.temp_trait: + if hasattr(self.this_trait, 'locus_chr') and self.this_trait.locus_chr != "" and self.dataset.type != "Geno" and self.dataset.type != "Publish": + hddn['control_marker'] = self.nearest_marker + #hddn['control_marker'] = self.nearest_marker1+","+self.nearest_marker2 hddn['do_control'] = False hddn['maf'] = 0.01 hddn['compare_traits'] = [] @@ -118,11 +144,12 @@ class ShowTrait(object): self.trait_table_width = get_trait_table_width(self.sample_groups) - if self.this_trait.symbol: - trait_symbol = self.this_trait.symbol - else: - trait_symbol = None - js_data = dict(trait_id = self.this_trait.name, + trait_symbol = None + if not self.temp_trait: + if self.this_trait.symbol: + trait_symbol = self.this_trait.symbol + + js_data = dict(trait_id = self.trait_id, trait_symbol = trait_symbol, dataset_type = self.dataset.type, data_scale = self.dataset.data_scale, @@ -149,7 +176,7 @@ class ShowTrait(object): else: return False - self.genofiles = get_genofiles(self.this_trait) + self.genofiles = get_genofiles(self.dataset) self.use_plink_gemma = check_plink_gemma() self.use_pylmm_rqtl = check_pylmm_rqtl() @@ -173,8 +200,8 @@ class ShowTrait(object): dataset_menu = data_set.datasets(this_group, self.dataset.group) dataset_menu_selected = None if len(dataset_menu): - if self.this_trait and self.this_trait.dataset: - dataset_menu_selected = self.this_trait.dataset.name + if self.dataset: + dataset_menu_selected = self.dataset.name return_results_menu = (100, 200, 500, 1000, 2000, 5000, 10000, 15000, 20000) return_results_menu_selected = 500 @@ -185,52 +212,57 @@ class ShowTrait(object): return_results_menu_selected = return_results_menu_selected,) - def make_sample_lists(self, this_trait): + def make_sample_lists(self): all_samples_ordered = self.dataset.group.all_samples_ordered() primary_sample_names = list(all_samples_ordered) - other_sample_names = [] - for sample in this_trait.data.keys(): - if (this_trait.data[sample].name2 in primary_sample_names) and (this_trait.data[sample].name not in primary_sample_names): - primary_sample_names.append(this_trait.data[sample].name) - primary_sample_names.remove(this_trait.data[sample].name2) - elif sample not in all_samples_ordered: - all_samples_ordered.append(sample) - other_sample_names.append(sample) - - if self.dataset.group.species == "human": - primary_sample_names += other_sample_names - - primary_samples = SampleList(dataset = self.dataset, - sample_names=primary_sample_names, - this_trait=this_trait, - sample_group_type='primary', - header="%s Only" % (self.dataset.group.name)) - logger.debug("primary_samples is: ", pf(primary_samples)) - - logger.debug("other_sample_names2:", other_sample_names) - if other_sample_names and self.dataset.group.species != "human" and self.dataset.group.name != "CFW": - parent_f1_samples = None - if self.dataset.group.parlist and self.dataset.group.f1list: - parent_f1_samples = self.dataset.group.parlist + self.dataset.group.f1list - - other_sample_names.sort() #Sort other samples - if parent_f1_samples: - other_sample_names = parent_f1_samples + other_sample_names - - logger.debug("other_sample_names:", other_sample_names) - - other_samples = SampleList(dataset=self.dataset, - sample_names=other_sample_names, - this_trait=this_trait, - sample_group_type='other', - header="Non-%s" % (self.dataset.group.name)) - - self.sample_groups = (primary_samples, other_samples) + 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: + all_samples_ordered.append(sample) + other_sample_names.append(sample) + + if self.dataset.group.species == "human": + primary_sample_names += other_sample_names + + primary_samples = SampleList(dataset = self.dataset, + sample_names=primary_sample_names, + this_trait=self.this_trait, + sample_group_type='primary', + header="%s Only" % (self.dataset.group.name)) + + if other_sample_names and self.dataset.group.species != "human" and self.dataset.group.name != "CFW": + parent_f1_samples = None + if self.dataset.group.parlist and self.dataset.group.f1list: + parent_f1_samples = self.dataset.group.parlist + self.dataset.group.f1list + + other_sample_names.sort() #Sort other samples + if parent_f1_samples: + other_sample_names = parent_f1_samples + other_sample_names + + logger.debug("other_sample_names:", other_sample_names) + + other_samples = SampleList(dataset=self.dataset, + sample_names=other_sample_names, + this_trait=self.this_trait, + sample_group_type='other', + header="Non-%s" % (self.dataset.group.name)) + + self.sample_groups = (primary_samples, other_samples) + else: + self.sample_groups = (primary_samples,) else: + primary_samples = SampleList(dataset = self.dataset, + sample_names=primary_sample_names, + this_trait=self.trait_vals, + sample_group_type='primary', + header="%s Only" % (self.dataset.group.name)) self.sample_groups = (primary_samples,) - #TODO: Figure out why this if statement is written this way - Zach #if (other_sample_names or (fd.f1list and this_trait.data.has_key(fd.f1list[0])) # or (fd.f1list and this_trait.data.has_key(fd.f1list[1]))): @@ -261,8 +293,8 @@ def get_nearest_marker(this_trait, this_db): return result[0][0] #return result[0][0], result[1][0] -def get_genofiles(this_trait): - jsonfile = "%s/%s.json" % (webqtlConfig.GENODIR, this_trait.dataset.group.name) +def get_genofiles(this_dataset): + jsonfile = "%s/%s.json" % (webqtlConfig.GENODIR, this_dataset.group.name) try: f = open(jsonfile) except: @@ -271,7 +303,7 @@ def get_genofiles(this_trait): return jsondata['genofile'] def get_trait_table_width(sample_groups): - table_width = 20 + table_width = 25 if sample_groups[0].se_exists(): table_width += 15 if (table_width + len(sample_groups[0].attributes)*10) > 100: diff --git a/wqflask/wqflask/static/new/javascript/draw_probability_plot.js b/wqflask/wqflask/static/new/javascript/draw_probability_plot.js index e5787564..f23dad0c 100644 --- a/wqflask/wqflask/static/new/javascript/draw_probability_plot.js +++ b/wqflask/wqflask/static/new/javascript/draw_probability_plot.js @@ -45,7 +45,7 @@ chart = nv.models.scatterChart().width(w).height(h).showLegend(true).color(d3.scale.category10().range()); chart.pointRange([50, 50]); chart.legend.updateState(false); - chart.xAxis.axisLabel("Expected Z score").tickFormat(d3.format('.02f')); + chart.xAxis.axisLabel("Expected Z score").axisLabelDistance(20).tickFormat(d3.format('.02f')); chart.tooltipContent(function(obj) { return '' + obj.point.name + ''; }); @@ -78,13 +78,19 @@ } return results; })(); - chart.yAxis.axisLabel("Trait value").tickFormat(d3.format('.0'+max_decimals.toString()+'f')); + //ZS: 0.1 indicates buffer, increase to increase buffer + y_domain = [sorted_values[0] - (sorted_values.slice(-1)[0] - sorted_values[0])*0.1, sorted_values.slice(-1)[0] + (sorted_values.slice(-1)[0] - sorted_values[0])*0.1] + chart.yDomain(y_domain) + chart.yAxis.axisLabel("Trait value").axisLabelDistance(10).tickFormat(d3.format('.0'+max_decimals.toString()+'f')); sw_result = ShapiroWilkW(sorted_values); W = sw_result.w.toFixed(3); pvalue = sw_result.p.toFixed(3); pvalue_str = pvalue > 0.05 ? pvalue.toString() : "" + pvalue + ""; test_str = "Shapiro-Wilk test statistic is " + W + " (p = " + pvalue_str + ")"; z_scores = get_z_scores(sorted_values.length); + //ZS: 0.1 indicates buffer, increase to increase buffer + x_domain = [z_scores[0] - (z_scores.slice(-1)[0] - z_scores[0])*0.1, z_scores.slice(-1)[0] + (z_scores.slice(-1)[0] - z_scores[0])*0.1] + chart.xDomain(x_domain) slope = jStat.stdev(sorted_values); intercept = jStat.mean(sorted_values); make_data = function(group_name) { diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 8223a38c..bb1af326 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -195,7 +195,7 @@ } row_line = ""; if (row.url != null) { - row_line += "" + row.pretty + ""; + row_line += "" + row.pretty + ""; } else { row_line += "" + row.pretty + ""; } diff --git a/wqflask/wqflask/static/new/packages/nvd3/nv.d3.css b/wqflask/wqflask/static/new/packages/nvd3/nv.d3.css index 694b9218..593d3889 100644 --- a/wqflask/wqflask/static/new/packages/nvd3/nv.d3.css +++ b/wqflask/wqflask/static/new/packages/nvd3/nv.d3.css @@ -1,96 +1,96 @@ /* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-05-25 */ -.nvd3 .nv-axis { - pointer-events:none; - opacity: 1; -} - -.nvd3 .nv-axis path { - fill: none; - stroke: #000; - stroke-opacity: .75; - shape-rendering: crispEdges; -} - -.nvd3 .nv-axis path.domain { - stroke-opacity: .75; -} - -.nvd3 .nv-axis.nv-x path.domain { - stroke-opacity: 1; -} - -.nvd3 .nv-axis line { - fill: none; - stroke: #e5e5e5; - shape-rendering: crispEdges; -} - -.nvd3 .nv-axis .zero line, - /*this selector may not be necessary*/ .nvd3 .nv-axis line.zero { - stroke-opacity: .75; -} - -.nvd3 .nv-axis .nv-axisMaxMin text { - font-weight: bold; -} - -.nvd3 .x .nv-axis .nv-axisMaxMin text, -.nvd3 .x2 .nv-axis .nv-axisMaxMin text, -.nvd3 .x3 .nv-axis .nv-axisMaxMin text { - text-anchor: middle -} - -.nvd3 .nv-axis.nv-disabled { - opacity: 0; -} - -.nvd3 .nv-bars rect { - fill-opacity: .75; - - transition: fill-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear; -} - -.nvd3 .nv-bars rect.hover { - fill-opacity: 1; -} - -.nvd3 .nv-bars .hover rect { - fill: lightblue; -} - -.nvd3 .nv-bars text { - fill: rgba(0,0,0,0); -} - -.nvd3 .nv-bars .hover text { - fill: rgba(0,0,0,1); -} - -.nvd3 .nv-multibar .nv-groups rect, -.nvd3 .nv-multibarHorizontal .nv-groups rect, -.nvd3 .nv-discretebar .nv-groups rect { - stroke-opacity: 0; - - transition: fill-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear; -} - -.nvd3 .nv-multibar .nv-groups rect:hover, -.nvd3 .nv-multibarHorizontal .nv-groups rect:hover, -.nvd3 .nv-candlestickBar .nv-ticks rect:hover, -.nvd3 .nv-discretebar .nv-groups rect:hover { - fill-opacity: 1; -} - -.nvd3 .nv-discretebar .nv-groups text, -.nvd3 .nv-multibarHorizontal .nv-groups text { - font-weight: bold; - fill: rgba(0,0,0,1); - stroke: rgba(0,0,0,0); -} +.nvd3 .nv-axis { + pointer-events:none; + opacity: 1; +} + +.nvd3 .nv-axis path { + fill: none; + stroke: #000; + stroke-opacity: .75; + shape-rendering: crispEdges; +} + +.nvd3 .nv-axis path.domain { + stroke-opacity: .75; +} + +.nvd3 .nv-axis.nv-x path.domain { + stroke-opacity: 1; +} + +.nvd3 .nv-axis line { + fill: none; + stroke: #e5e5e5; + shape-rendering: crispEdges; +} + +.nvd3 .nv-axis .zero line, + /*this selector may not be necessary*/ .nvd3 .nv-axis line.zero { + stroke-opacity: .75; +} + +.nvd3 .nv-axis .nv-axisMaxMin text { + font-weight: bold; +} + +.nvd3 .x .nv-axis .nv-axisMaxMin text, +.nvd3 .x2 .nv-axis .nv-axisMaxMin text, +.nvd3 .x3 .nv-axis .nv-axisMaxMin text { + text-anchor: middle +} + +.nvd3 .nv-axis.nv-disabled { + opacity: 0; +} + +.nvd3 .nv-bars rect { + fill-opacity: .75; + + transition: fill-opacity 250ms linear; + -moz-transition: fill-opacity 250ms linear; + -webkit-transition: fill-opacity 250ms linear; +} + +.nvd3 .nv-bars rect.hover { + fill-opacity: 1; +} + +.nvd3 .nv-bars .hover rect { + fill: lightblue; +} + +.nvd3 .nv-bars text { + fill: rgba(0,0,0,0); +} + +.nvd3 .nv-bars .hover text { + fill: rgba(0,0,0,1); +} + +.nvd3 .nv-multibar .nv-groups rect, +.nvd3 .nv-multibarHorizontal .nv-groups rect, +.nvd3 .nv-discretebar .nv-groups rect { + stroke-opacity: 0; + + transition: fill-opacity 250ms linear; + -moz-transition: fill-opacity 250ms linear; + -webkit-transition: fill-opacity 250ms linear; +} + +.nvd3 .nv-multibar .nv-groups rect:hover, +.nvd3 .nv-multibarHorizontal .nv-groups rect:hover, +.nvd3 .nv-candlestickBar .nv-ticks rect:hover, +.nvd3 .nv-discretebar .nv-groups rect:hover { + fill-opacity: 1; +} + +.nvd3 .nv-discretebar .nv-groups text, +.nvd3 .nv-multibarHorizontal .nv-groups text { + font-weight: bold; + fill: rgba(0,0,0,1); + stroke: rgba(0,0,0,0); +} /* boxplot CSS */ .nvd3 .nv-boxplot circle { @@ -112,57 +112,57 @@ .nv-boxplot-tick:hover { stroke-width: 2.5px; } -/* bullet */ -.nvd3.nv-bullet { font: 10px sans-serif; } -.nvd3.nv-bullet .nv-measure { fill-opacity: .8; } -.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; } -.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; } -.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; } -.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; } -.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; } -.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; } -.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; } -.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; } -.nvd3.nv-bullet .nv-subtitle { fill: #999; } - - -.nvd3.nv-bullet .nv-range { - fill: #bababa; - fill-opacity: .4; -} -.nvd3.nv-bullet .nv-range:hover { - fill-opacity: .7; -} - -.nvd3.nv-candlestickBar .nv-ticks .nv-tick { - stroke-width: 1px; -} - -.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover { - stroke-width: 2px; -} - -.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect { - stroke: #2ca02c; - fill: #2ca02c; -} - -.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect { - stroke: #d62728; - fill: #d62728; -} - -.with-transitions .nv-candlestickBar .nv-ticks .nv-tick { - transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -} - -.nvd3.nv-candlestickBar .nv-ticks line { - stroke: #333; -} - +/* bullet */ +.nvd3.nv-bullet { font: 10px sans-serif; } +.nvd3.nv-bullet .nv-measure { fill-opacity: .8; } +.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; } +.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; } +.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; } +.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; } +.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; } +.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; } +.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; } +.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; } +.nvd3.nv-bullet .nv-subtitle { fill: #999; } + + +.nvd3.nv-bullet .nv-range { + fill: #bababa; + fill-opacity: .4; +} +.nvd3.nv-bullet .nv-range:hover { + fill-opacity: .7; +} + +.nvd3.nv-candlestickBar .nv-ticks .nv-tick { + stroke-width: 1px; +} + +.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover { + stroke-width: 2px; +} + +.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect { + stroke: #2ca02c; + fill: #2ca02c; +} + +.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect { + stroke: #d62728; + fill: #d62728; +} + +.with-transitions .nv-candlestickBar .nv-ticks .nv-tick { + transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + +} + +.nvd3.nv-candlestickBar .nv-ticks line { + stroke: #333; +} + .nvd3 .nv-legend .nv-disabled rect { /*fill-opacity: 0;*/ @@ -187,455 +187,455 @@ opacity: 0; } -/* line plus bar */ -.nvd3.nv-linePlusBar .nv-bar rect { - fill-opacity: .75; -} - -.nvd3.nv-linePlusBar .nv-bar rect:hover { - fill-opacity: 1; -} -.nvd3 .nv-groups path.nv-line { - fill: none; -} - -.nvd3 .nv-groups path.nv-area { - stroke: none; -} - -.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point { - fill-opacity: 0; - stroke-opacity: 0; -} - -.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point { - fill-opacity: .5 !important; - stroke-opacity: .5 !important; -} - - -.with-transitions .nvd3 .nv-groups .nv-point { - transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; - -} - -.nvd3.nv-scatter .nv-groups .nv-point.hover, -.nvd3 .nv-groups .nv-point.hover { - stroke-width: 7px; - fill-opacity: .95 !important; - stroke-opacity: .95 !important; -} - - -.nvd3 .nv-point-paths path { - stroke: #aaa; - stroke-opacity: 0; - fill: #eee; - fill-opacity: 0; -} - - - -.nvd3 .nv-indexLine { - cursor: ew-resize; -} - -/******************** - * SVG CSS - */ - -/******************** - Default CSS for an svg element nvd3 used -*/ -svg.nvd3-svg { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -ms-user-select: none; - -moz-user-select: none; - user-select: none; - display: block; - width:100%; - height:100%; -} - -/******************** - Box shadow and border radius styling -*/ -.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip { - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); - - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - - -.nvd3 text { - font: normal 12px Arial; -} - -.nvd3 .title { - font: bold 14px Arial; -} - -.nvd3 .nv-background { - fill: white; - fill-opacity: 0; -} - -.nvd3.nv-noData { - font-size: 18px; - font-weight: bold; -} - - -/********** -* Brush -*/ - -.nv-brush .extent { - fill-opacity: .125; - shape-rendering: crispEdges; -} - -.nv-brush .resize path { - fill: #eee; - stroke: #666; -} - - -/********** -* Legend -*/ - -.nvd3 .nv-legend .nv-series { - cursor: pointer; -} - -.nvd3 .nv-legend .nv-disabled circle { - fill-opacity: 0; -} - -/* focus */ -.nvd3 .nv-brush .extent { - fill-opacity: 0 !important; -} - -.nvd3 .nv-brushBackground rect { - stroke: #000; - stroke-width: .4; - fill: #fff; - fill-opacity: .7; -} - - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick { - stroke-width: 1px; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover { - stroke-width: 2px; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive { - stroke: #2ca02c; -} - -.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative { - stroke: #d62728; -} - - -.nvd3 .background path { - fill: none; - stroke: #EEE; - stroke-opacity: .4; - shape-rendering: crispEdges; -} - -.nvd3 .foreground path { - fill: none; - stroke-opacity: .7; -} - -.nvd3 .nv-parallelCoordinates-brush .extent -{ - fill: #fff; - fill-opacity: .6; - stroke: gray; - shape-rendering: crispEdges; -} - -.nvd3 .nv-parallelCoordinates .hover { - fill-opacity: 1; - stroke-width: 3px; -} - - -.nvd3 .missingValuesline line { - fill: none; - stroke: black; - stroke-width: 1; - stroke-opacity: 1; - stroke-dasharray: 5, 5; -} -.nvd3.nv-pie path { - stroke-opacity: 0; - transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; - -} - -.nvd3.nv-pie .nv-pie-title { - font-size: 24px; - fill: rgba(19, 196, 249, 0.59); -} - -.nvd3.nv-pie .nv-slice text { - stroke: #000; - stroke-width: 0; -} - -.nvd3.nv-pie path { - stroke: #fff; - stroke-width: 1px; - stroke-opacity: 1; -} - -.nvd3.nv-pie .hover path { - fill-opacity: .7; -} -.nvd3.nv-pie .nv-label { - pointer-events: none; -} -.nvd3.nv-pie .nv-label rect { - fill-opacity: 0; - stroke-opacity: 0; -} - -/* scatter */ -.nvd3 .nv-groups .nv-point.hover { - stroke-width: 20px; - stroke-opacity: .5; -} - -.nvd3 .nv-scatter .nv-point.hover { - fill-opacity: 1; -} -.nv-noninteractive { - pointer-events: none; -} - -.nv-distx, .nv-disty { - pointer-events: none; -} - -/* sparkline */ -.nvd3.nv-sparkline path { - fill: none; -} - -.nvd3.nv-sparklineplus g.nv-hoverValue { - pointer-events: none; -} - -.nvd3.nv-sparklineplus .nv-hoverValue line { - stroke: #333; - stroke-width: 1.5px; -} - -.nvd3.nv-sparklineplus, -.nvd3.nv-sparklineplus g { - pointer-events: all; -} - -.nvd3 .nv-hoverArea { - fill-opacity: 0; - stroke-opacity: 0; -} - -.nvd3.nv-sparklineplus .nv-xValue, -.nvd3.nv-sparklineplus .nv-yValue { - stroke-width: 0; - font-size: .9em; - font-weight: normal; -} - -.nvd3.nv-sparklineplus .nv-yValue { - stroke: #f66; -} - -.nvd3.nv-sparklineplus .nv-maxValue { - stroke: #2ca02c; - fill: #2ca02c; -} - -.nvd3.nv-sparklineplus .nv-minValue { - stroke: #d62728; - fill: #d62728; -} - -.nvd3.nv-sparklineplus .nv-currentValue { - font-weight: bold; - font-size: 1.1em; -} -/* stacked area */ -.nvd3.nv-stackedarea path.nv-area { - fill-opacity: .7; - stroke-opacity: 0; - transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; - -moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; - -webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; -} - -.nvd3.nv-stackedarea path.nv-area.hover { - fill-opacity: .9; -} - - -.nvd3.nv-stackedarea .nv-groups .nv-point { - stroke-opacity: 0; - fill-opacity: 0; -} - - -.nvtooltip { - position: absolute; - background-color: rgba(255,255,255,1.0); - color: rgba(0,0,0,1.0); - padding: 1px; - border: 1px solid rgba(0,0,0,.2); - z-index: 10000; - display: block; - - font-family: Arial; - font-size: 13px; - text-align: left; - pointer-events: none; - - white-space: nowrap; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.nvtooltip { - background: rgba(255,255,255, 0.8); - border: 1px solid rgba(0,0,0,0.5); - border-radius: 4px; -} - -/*Give tooltips that old fade in transition by - putting a "with-transitions" class on the container div. -*/ -.nvtooltip.with-transitions, .with-transitions .nvtooltip { - transition: opacity 50ms linear; - -moz-transition: opacity 50ms linear; - -webkit-transition: opacity 50ms linear; - - transition-delay: 200ms; - -moz-transition-delay: 200ms; - -webkit-transition-delay: 200ms; -} - -.nvtooltip.x-nvtooltip, -.nvtooltip.y-nvtooltip { - padding: 8px; -} - -.nvtooltip h3 { - margin: 0; - padding: 4px 14px; - line-height: 18px; - font-weight: normal; - background-color: rgba(247,247,247,0.75); - color: rgba(0,0,0,1.0); - text-align: center; - - border-bottom: 1px solid #ebebeb; - - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} - -.nvtooltip p { - margin: 0; - padding: 5px 14px; - text-align: center; -} - -.nvtooltip span { - display: inline-block; - margin: 2px 0; -} - -.nvtooltip table { - margin: 6px; - border-spacing:0; -} - - -.nvtooltip table td { - padding: 2px 9px 2px 0; - vertical-align: middle; -} - -.nvtooltip table td.key { - font-weight:normal; -} -.nvtooltip table td.value { - text-align: right; - font-weight: bold; -} - -.nvtooltip table tr.highlight td { - padding: 1px 9px 1px 0; - border-bottom-style: solid; - border-bottom-width: 1px; - border-top-style: solid; - border-top-width: 1px; -} - -.nvtooltip table td.legend-color-guide div { - width: 8px; - height: 8px; - vertical-align: middle; -} - -.nvtooltip table td.legend-color-guide div { - width: 12px; - height: 12px; - border: 1px solid #999; -} - -.nvtooltip .footer { - padding: 3px; - text-align: center; -} - -.nvtooltip-pending-removal { - pointer-events: none; - display: none; -} - - -/**** -Interactive Layer -*/ -.nvd3 .nv-interactiveGuideLine { - pointer-events:none; -} -.nvd3 line.nv-guideline { - stroke: #ccc; +/* line plus bar */ +.nvd3.nv-linePlusBar .nv-bar rect { + fill-opacity: .75; +} + +.nvd3.nv-linePlusBar .nv-bar rect:hover { + fill-opacity: 1; +} +.nvd3 .nv-groups path.nv-line { + fill: none; +} + +.nvd3 .nv-groups path.nv-area { + stroke: none; +} + +.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point { + fill-opacity: 0; + stroke-opacity: 0; +} + +.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point { + fill-opacity: .5 !important; + stroke-opacity: .5 !important; +} + + +.with-transitions .nvd3 .nv-groups .nv-point { + transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; + +} + +.nvd3.nv-scatter .nv-groups .nv-point.hover, +.nvd3 .nv-groups .nv-point.hover { + stroke-width: 7px; + fill-opacity: .95 !important; + stroke-opacity: .95 !important; +} + + +.nvd3 .nv-point-paths path { + stroke: #aaa; + stroke-opacity: 0; + fill: #eee; + fill-opacity: 0; +} + + + +.nvd3 .nv-indexLine { + cursor: ew-resize; +} + +/******************** + * SVG CSS + */ + +/******************** + Default CSS for an svg element nvd3 used +*/ +svg.nvd3-svg { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -moz-user-select: none; + user-select: none; + display: block; + width:100%; + height:100%; +} + +/******************** + Box shadow and border radius styling +*/ +.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip { + -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); + box-shadow: 0 5px 10px rgba(0,0,0,.2); + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + + +.nvd3 text { + font: normal 14px Arial; +} + +.nvd3 .title { + font: bold 14px Arial; +} + +.nvd3 .nv-background { + fill: white; + fill-opacity: 0; +} + +.nvd3.nv-noData { + font-size: 18px; + font-weight: bold; +} + + +/********** +* Brush +*/ + +.nv-brush .extent { + fill-opacity: .125; + shape-rendering: crispEdges; +} + +.nv-brush .resize path { + fill: #eee; + stroke: #666; +} + + +/********** +* Legend +*/ + +.nvd3 .nv-legend .nv-series { + cursor: pointer; +} + +.nvd3 .nv-legend .nv-disabled circle { + fill-opacity: 0; +} + +/* focus */ +.nvd3 .nv-brush .extent { + fill-opacity: 0 !important; +} + +.nvd3 .nv-brushBackground rect { + stroke: #000; + stroke-width: .4; + fill: #fff; + fill-opacity: .7; +} + + +.nvd3.nv-ohlcBar .nv-ticks .nv-tick { + stroke-width: 1px; +} + +.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover { + stroke-width: 2px; +} + +.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive { + stroke: #2ca02c; +} + +.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative { + stroke: #d62728; +} + + +.nvd3 .background path { + fill: none; + stroke: #EEE; + stroke-opacity: .4; + shape-rendering: crispEdges; +} + +.nvd3 .foreground path { + fill: none; + stroke-opacity: .7; +} + +.nvd3 .nv-parallelCoordinates-brush .extent +{ + fill: #fff; + fill-opacity: .6; + stroke: gray; + shape-rendering: crispEdges; +} + +.nvd3 .nv-parallelCoordinates .hover { + fill-opacity: 1; + stroke-width: 3px; +} + + +.nvd3 .missingValuesline line { + fill: none; + stroke: black; + stroke-width: 1; + stroke-opacity: 1; + stroke-dasharray: 5, 5; +} +.nvd3.nv-pie path { + stroke-opacity: 0; + transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; + -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; + -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; + +} + +.nvd3.nv-pie .nv-pie-title { + font-size: 24px; + fill: rgba(19, 196, 249, 0.59); +} + +.nvd3.nv-pie .nv-slice text { + stroke: #000; + stroke-width: 0; +} + +.nvd3.nv-pie path { + stroke: #fff; + stroke-width: 1px; + stroke-opacity: 1; +} + +.nvd3.nv-pie .hover path { + fill-opacity: .7; +} +.nvd3.nv-pie .nv-label { + pointer-events: none; +} +.nvd3.nv-pie .nv-label rect { + fill-opacity: 0; + stroke-opacity: 0; +} + +/* scatter */ +.nvd3 .nv-groups .nv-point.hover { + stroke-width: 20px; + stroke-opacity: .5; +} + +.nvd3 .nv-scatter .nv-point.hover { + fill-opacity: 1; +} +.nv-noninteractive { + pointer-events: none; +} + +.nv-distx, .nv-disty { + pointer-events: none; +} + +/* sparkline */ +.nvd3.nv-sparkline path { + fill: none; +} + +.nvd3.nv-sparklineplus g.nv-hoverValue { + pointer-events: none; +} + +.nvd3.nv-sparklineplus .nv-hoverValue line { + stroke: #333; + stroke-width: 1.5px; +} + +.nvd3.nv-sparklineplus, +.nvd3.nv-sparklineplus g { + pointer-events: all; +} + +.nvd3 .nv-hoverArea { + fill-opacity: 0; + stroke-opacity: 0; +} + +.nvd3.nv-sparklineplus .nv-xValue, +.nvd3.nv-sparklineplus .nv-yValue { + stroke-width: 0; + font-size: .9em; + font-weight: normal; +} + +.nvd3.nv-sparklineplus .nv-yValue { + stroke: #f66; +} + +.nvd3.nv-sparklineplus .nv-maxValue { + stroke: #2ca02c; + fill: #2ca02c; +} + +.nvd3.nv-sparklineplus .nv-minValue { + stroke: #d62728; + fill: #d62728; +} + +.nvd3.nv-sparklineplus .nv-currentValue { + font-weight: bold; + font-size: 1.1em; +} +/* stacked area */ +.nvd3.nv-stackedarea path.nv-area { + fill-opacity: .7; + stroke-opacity: 0; + transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; + -moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; + -webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; +} + +.nvd3.nv-stackedarea path.nv-area.hover { + fill-opacity: .9; +} + + +.nvd3.nv-stackedarea .nv-groups .nv-point { + stroke-opacity: 0; + fill-opacity: 0; +} + + +.nvtooltip { + position: absolute; + background-color: rgba(255,255,255,1.0); + color: rgba(0,0,0,1.0); + padding: 1px; + border: 1px solid rgba(0,0,0,.2); + z-index: 10000; + display: block; + + font-family: Arial; + font-size: 13px; + text-align: left; + pointer-events: none; + + white-space: nowrap; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.nvtooltip { + background: rgba(255,255,255, 0.8); + border: 1px solid rgba(0,0,0,0.5); + border-radius: 4px; +} + +/*Give tooltips that old fade in transition by + putting a "with-transitions" class on the container div. +*/ +.nvtooltip.with-transitions, .with-transitions .nvtooltip { + transition: opacity 50ms linear; + -moz-transition: opacity 50ms linear; + -webkit-transition: opacity 50ms linear; + + transition-delay: 200ms; + -moz-transition-delay: 200ms; + -webkit-transition-delay: 200ms; +} + +.nvtooltip.x-nvtooltip, +.nvtooltip.y-nvtooltip { + padding: 8px; +} + +.nvtooltip h3 { + margin: 0; + padding: 4px 14px; + line-height: 18px; + font-weight: normal; + background-color: rgba(247,247,247,0.75); + color: rgba(0,0,0,1.0); + text-align: center; + + border-bottom: 1px solid #ebebeb; + + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.nvtooltip p { + margin: 0; + padding: 5px 14px; + text-align: center; +} + +.nvtooltip span { + display: inline-block; + margin: 2px 0; +} + +.nvtooltip table { + margin: 6px; + border-spacing:0; +} + + +.nvtooltip table td { + padding: 2px 9px 2px 0; + vertical-align: middle; +} + +.nvtooltip table td.key { + font-weight:normal; +} +.nvtooltip table td.value { + text-align: right; + font-weight: bold; +} + +.nvtooltip table tr.highlight td { + padding: 1px 9px 1px 0; + border-bottom-style: solid; + border-bottom-width: 1px; + border-top-style: solid; + border-top-width: 1px; +} + +.nvtooltip table td.legend-color-guide div { + width: 8px; + height: 8px; + vertical-align: middle; +} + +.nvtooltip table td.legend-color-guide div { + width: 12px; + height: 12px; + border: 1px solid #999; +} + +.nvtooltip .footer { + padding: 3px; + text-align: center; +} + +.nvtooltip-pending-removal { + pointer-events: none; + display: none; +} + + +/**** +Interactive Layer +*/ +.nvd3 .nv-interactiveGuideLine { + pointer-events:none; +} +.nvd3 line.nv-guideline { + stroke: #ccc; } \ No newline at end of file diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index cedb65a1..3bde7dc7 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -32,65 +32,65 @@

-
+
- + {% for header in target_dataset.header_fields %} {% if header == 'Year' %} - + {% elif header == 'Max LRS' %} - + {% elif header == 'Max LRS Location' %} - + {% elif header == 'Location' %} - + {% elif header == 'Mean' %} - + {% elif header == 'Additive Effect' %} - + {% elif header == 'Index' %} - + {% elif header == 'N' %} - + {% else %} - + {% endif %} {% endfor %} {% if target_dataset.type == "ProbeSet" %} {% if corr_method == 'pearson' %} - - - - - + + + + + {% else %} - - - - - + + + + + {% endif %} {% elif target_dataset.type == "Publish" %} {% if corr_method == 'pearson' %} - - - + + + {% else %} - - - + + + {% endif %} {% elif target_dataset.type == "Geno" %} {% if corr_method == 'pearson' %} - - - + + + {% else %} - - - + + + {% endif %} {% endif %} @@ -99,7 +99,7 @@ {% for trait in correlation_results %} - + - - - - - - + + + + + + {% if trait.lit_corr == "" or trait.lit_corr == 0.000 %} - + {% else %} - + {% endif %} {% if trait.tissue_corr == "" or trait.tissue_corr == 0.000 %} - + {% else %} - + {% endif %} {% elif target_dataset.type == "Publish" %} @@ -138,17 +138,17 @@ {{ trait.pubmed_text }} - - - - - - + + + + + + {% elif target_dataset.type == "Geno" %} - - - - + + + + {% endif %} {% endfor %} @@ -278,6 +278,13 @@ { "type": "natural" }, { "type": "natural" } ], + "createdRow": function ( row, data, index ) { + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + if ($('td', row).eq(4).text().length > 60) { + $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 60)); + $('td', row).eq(4).text($('td', row).eq(4).text() + '...') + } + }, "order": [[12, "asc" ]], "sDom": "Btir", "autoWidth": false, @@ -287,7 +294,6 @@ } ); var table = $('#trait_table').DataTable(); - new $.fn.dataTable.FixedHeader( table ); {% elif target_dataset.type == "Publish" %} $('#trait_table').dataTable( { @@ -311,7 +317,7 @@ { "type": "natural" }, { "type": "natural" }, { "type": "natural", "width": "25%" }, - { "type": "natural", "width": "10%" }, + { "type": "natural", "width": "15%" }, { "type": "natural" }, { "type": "natural" }, { "type": "natural" }, @@ -320,6 +326,13 @@ { "type": "natural" }, { "type": "scientific" } ], + "createdRow": function ( row, data, index ) { + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + if ($('td', row).eq(4).text().length > 60) { + $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 60)); + $('td', row).eq(4).text($('td', row).eq(4).text() + '...') + } + }, "order": [[11, "asc" ]], "sDom": "Btir", "autoWidth": false, diff --git a/wqflask/wqflask/templates/index_page_orig.html b/wqflask/wqflask/templates/index_page_orig.html index 1694eae5..72ced084 100755 --- a/wqflask/wqflask/templates/index_page_orig.html +++ b/wqflask/wqflask/templates/index_page_orig.html @@ -173,6 +173,16 @@
+
+ + +
- {% if mapping_method != "gemma" %} + {% if mapping_method != "gemma" and mapping_method != "plink" %}
@@ -277,11 +277,13 @@ + {% if mapping_method != "gemma" and mapping_method != "plink" %} + {% endif %} - {% if mapping_method != "gemma" %} + {% if mapping_method != "gemma" and mapping_method != "plink" %} @@ -385,6 +387,7 @@ return $('#marker_regression_form').submit(); }; + {% if mapping_method != "gemma" and mapping_method != "plink" %} export_perm_data = function() { var num_perm, perm_data; num_perm = js_data.num_perm @@ -393,7 +396,8 @@ $('input[name=perm_results]').val(json_perm_data); $('#marker_regression_form').attr('action', '/export_perm_data'); return $('#marker_regression_form').submit(); - }; + } + {% endif %} diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 772c4314..56b6cc62 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -17,7 +17,9 @@ {% block content %} diff --git a/wqflask/wqflask/templates/submit_trait.html b/wqflask/wqflask/templates/submit_trait.html index 2529a4f4..8d624ffd 100644 --- a/wqflask/wqflask/templates/submit_trait.html +++ b/wqflask/wqflask/templates/submit_trait.html @@ -2,7 +2,7 @@ {% block title %}Trait Submission{% endblock %} {% block content %} -
+
{{ flash_me() }} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index ab6c433d..39f4a686 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -389,6 +389,20 @@ def export_perm_data(): mimetype='text/csv', headers={"Content-Disposition":"attachment;filename=perm_data.csv"}) +@app.route("/show_temp_trait", methods=('POST',)) +def show_temp_trait_page(): + template_vars = show_trait.ShowTrait(request.form) + #logger.info("js_data before dump:", template_vars.js_data) + template_vars.js_data = json.dumps(template_vars.js_data, + default=json_default_handler, + indent=" ") + # Sorting the keys messes up the ordered dictionary, so don't do that + #sort_keys=True) + + #logger.info("js_data after dump:", template_vars.js_data) + #logger.info("show_trait template_vars:", pf(template_vars.__dict__)) + return render_template("show_trait.html", **template_vars.__dict__) + @app.route("/show_trait") def show_trait_page(): template_vars = show_trait.ShowTrait(request.args) @@ -575,9 +589,10 @@ def marker_regression_page(): with Bench("Total time in MarkerRegression"): template_vars = marker_regression.MarkerRegression(start_vars, temp_uuid) - template_vars.js_data = json.dumps(template_vars.js_data, - default=json_default_handler, - indent=" ") + if template_vars.mapping_method != "gemma" and template_vars.mapping_method != "plink": + template_vars.js_data = json.dumps(template_vars.js_data, + default=json_default_handler, + indent=" ") result = template_vars.__dict__ @@ -598,13 +613,15 @@ def marker_regression_page(): # logger.info(" ---**--- {}: {}".format(type(template_vars.__dict__[item]), item)) gn1_template_vars = marker_regression_gn1.MarkerRegression(result).__dict__ - - pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL) - logger.info("pickled result length:", len(pickled_result)) - Redis.set(key, pickled_result) - Redis.expire(key, 1*60) + #pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL) + #logger.info("pickled result length:", len(pickled_result)) + #Redis.set(key, pickled_result) + #Redis.expire(key, 1*60) with Bench("Rendering template"): + if (gn1_template_vars['mapping_method'] == "gemma") or (gn1_template_vars['mapping_method'] == "plink"): + gn1_template_vars.pop('qtlresults', None) + print("TEMPLATE KEYS:", list(gn1_template_vars.keys())) rendered_template = render_template("marker_regression_gn1.html", **gn1_template_vars) # with Bench("Rendering template"): -- cgit v1.2.3 From f419b8bc824303009817ad9d52e1452b870b0039 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 5 Apr 2017 15:51:20 +0000 Subject: Added images directory with various gifs, etc --- wqflask/wqflask/static/new/images/a1.gif | Bin 0 -> 430 bytes wqflask/wqflask/static/new/images/arrowdown.gif | Bin 0 -> 844 bytes wqflask/wqflask/static/new/images/step1.gif | Bin 0 -> 758 bytes wqflask/wqflask/static/new/images/step2.gif | Bin 0 -> 826 bytes wqflask/wqflask/static/new/images/step3.gif | Bin 0 -> 818 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 wqflask/wqflask/static/new/images/a1.gif create mode 100644 wqflask/wqflask/static/new/images/arrowdown.gif create mode 100644 wqflask/wqflask/static/new/images/step1.gif create mode 100644 wqflask/wqflask/static/new/images/step2.gif create mode 100644 wqflask/wqflask/static/new/images/step3.gif diff --git a/wqflask/wqflask/static/new/images/a1.gif b/wqflask/wqflask/static/new/images/a1.gif new file mode 100644 index 00000000..283921a0 Binary files /dev/null and b/wqflask/wqflask/static/new/images/a1.gif differ diff --git a/wqflask/wqflask/static/new/images/arrowdown.gif b/wqflask/wqflask/static/new/images/arrowdown.gif new file mode 100644 index 00000000..577e5476 Binary files /dev/null and b/wqflask/wqflask/static/new/images/arrowdown.gif differ diff --git a/wqflask/wqflask/static/new/images/step1.gif b/wqflask/wqflask/static/new/images/step1.gif new file mode 100644 index 00000000..42d2bc7d Binary files /dev/null and b/wqflask/wqflask/static/new/images/step1.gif differ diff --git a/wqflask/wqflask/static/new/images/step2.gif b/wqflask/wqflask/static/new/images/step2.gif new file mode 100644 index 00000000..b3dca656 Binary files /dev/null and b/wqflask/wqflask/static/new/images/step2.gif differ diff --git a/wqflask/wqflask/static/new/images/step3.gif b/wqflask/wqflask/static/new/images/step3.gif new file mode 100644 index 00000000..0e0c7ea2 Binary files /dev/null and b/wqflask/wqflask/static/new/images/step3.gif differ -- cgit v1.2.3 From 2c94097c49eedff1def1fb7d53572f290b8fe7d1 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 17 Apr 2017 22:24:40 +0000 Subject: Added option to remove collections from collection list page Improved appearance of search result and collection tables --- wqflask/base/data_set.py | 2 +- wqflask/wqflask/collect.py | 19 +++-- .../packages/DataTables/css/jquery.dataTables.css | 15 ++-- wqflask/wqflask/templates/collections/list.html | 60 +++++++++++---- wqflask/wqflask/templates/collections/view.html | 86 ++++++++++++---------- wqflask/wqflask/templates/search_result_page.html | 27 +++---- 6 files changed, 130 insertions(+), 79 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 7f08135f..4959457a 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -893,7 +893,7 @@ class GenotypeDataSet(DataSet): def retrieve_sample_data(self, trait): query = """ SELECT - Strain.Name, GenoData.value, GenoSE.error, GenoData.Id, Sample.Name2 + Strain.Name, GenoData.value, GenoSE.error, GenoData.Id, Strain.Name2 FROM (GenoData, GenoFreeze, Strain, Geno, GenoXRef) left join GenoSE on diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 478dbcaa..2f6c3a96 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -335,12 +335,19 @@ def delete_collection(): print("params:", params) if g.user_session.logged_in: uc_id = params['uc_id'] - uc = model.UserCollection.query.get(uc_id) - # Todo: For now having the id is good enough since it's so unique - # But might want to check ownership in the future - collection_name = uc.name - db_session.delete(uc) - db_session.commit() + if len(uc_id.split(":")) > 1: + for this_uc_id in uc_id.split(":"): + uc = model.UserCollection.query.get(this_uc_id) + collection_name = uc.name + db_session.delete(uc) + db_session.commit() + else: + uc = model.UserCollection.query.get(uc_id) + # Todo: For now having the id is good enough since it's so unique + # But might want to check ownership in the future + collection_name = uc.name + db_session.delete(uc) + db_session.commit() else: collection_name = params['collection_name'] user_manager.AnonUser().delete_collection(collection_name) diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css index 40e58ac8..ab7420a6 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css @@ -14,6 +14,9 @@ table.dataTable { * Body styles */ } +td.highlight { + background-color: whitesmoke !important; +} table.dataTable thead th, table.dataTable tfoot th { font-weight: bold; @@ -25,8 +28,8 @@ table.dataTable thead td { background-color: #ffffff; border-collapse: collapse; border-bottom: #cccccc 2px solid; - padding: 0; - //padding: 10px 18px 10px 0px; + //padding: 0; + padding: 10px 18px 4px 10px; //border-bottom: 1px solid #111; } table.dataTable thead th:active, @@ -39,8 +42,8 @@ table.dataTable tfoot td { color: #000000; background-color: #ffffff; border-collapse: collapse; - padding: 0; - //padding: 10px 18px 6px 18px; + //padding: 0; + padding: 10px 18px 6px 18px; //border-top: 1px solid #111; } table.dataTable thead .sorting, @@ -76,12 +79,12 @@ table.dataTable tbody tr { background-color: #ffffff; } table.dataTable tbody tr.selected { - background-color: #ffff99; + background-color: #abb9d3; } table.dataTable tbody th, table.dataTable tbody td { font: 12px Arial, Sans-serif; - padding: 4px 16px 4px 0px; + padding: 8px 20px 6px 10px; } table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { border-top: 1px solid #ddd; diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html index 6dc52c4d..5a30c98c 100644 --- a/wqflask/wqflask/templates/collections/list.html +++ b/wqflask/wqflask/templates/collections/list.html @@ -25,11 +25,21 @@

Your Collections

{% endif %}
- +
+ + + + + + + +
+
-
{{header}}{{header}}Max  
LRS ?
Max LRS ?{{header}}{{header}}{{header}}{{header}}{{header}}{{header}}Add  
Effect ?
Additive Effect ?{{header}}{{header}}{{header}}{{header}}{{header}}{{header}}Sample r  NSample p(r)Lit rTissue rSample r  NSample p(r)Lit rTissue rSample rhoNSample p(rho)Lit rTissue rhoSample rhoNSample p(rho)Lit rTissue rhoSample r  NSample p(r)Sample r  NSample p(r)Sample rho  NSample p(rho)Sample rho  NSample p(rho)Sample rNSample p(r)Sample rNSample p(r)Sample rhoNSample p(rho)Sample rhoNSample p(rho)
   {{ loop.index }} {{ trait.location_repr }} {{ '%0.3f' % trait.mean|float }}{% if trait.LRS_score_repr != "N/A" %}{{ '%0.1f' % trait.LRS_score_repr|float }}{% else %}N/A{% endif %}{{ trait.LRS_location_repr }}{% if trait.additive != "" %}{{ '%0.3f' % trait.additive|float }}{% else %}N/A{% endif %}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}{% if trait.LRS_score_repr != "N/A" %}{{ '%0.1f' % trait.LRS_score_repr|float }}{% else %}N/A{% endif %}{{ trait.LRS_location_repr }}{% if trait.additive != "" %}{{ '%0.3f' % trait.additive|float }}{% else %}N/A{% endif %}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}----{{'%0.3f'|format(trait.lit_corr)}}{{'%0.3f'|format(trait.lit_corr)}}----{{'%0.3f'|format(trait.tissue_corr)}}{{'%0.3f'|format(trait.tissue_corr)}}{{ trait.description_display }} {{ trait.LRS_score_repr }}{{ trait.LRS_location_repr }}{% if trait.additive != "" %}{{ '%0.3f' % trait.additive|float }}{% else %}N/A{% endif %}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}{{ trait.LRS_score_repr }}{{ trait.LRS_location_repr }}{% if trait.additive != "" %}{{ '%0.3f' % trait.additive|float }}{% else %}N/A{% endif %}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}{{ trait.location_repr }}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}{{ trait.location_repr }}{{'%0.3f'|format(trait.sample_r)}}{{ trait.num_overlap }}{{'%0.3e'|format(trait.sample_p)}}
+
+ @@ -41,7 +51,8 @@ {% for uc in collections %} - + {% else %} @@ -64,6 +75,7 @@ {% block js %} + @@ -72,24 +84,24 @@ - - {% if "color_by_trait" in params %} {% endif %} {% endblock %} diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html index 9d03e6d7..094bc273 100644 --- a/wqflask/wqflask/templates/collections/view.html +++ b/wqflask/wqflask/templates/collections/view.html @@ -2,8 +2,7 @@ {% block title %}View Collection{% endblock %} {% block css %} - - + {% endblock %} {% block content %} @@ -29,42 +28,40 @@ {% for this_trait in trait_obs %} {{ this_trait.name }}:{{ this_trait.dataset.name }}, {% endfor %}" > -
+ -
-
+ + -
-
+ + -
-
+ + -
-
+ + -
-
+ + -
+
-
-

@@ -80,7 +77,7 @@
-
Index Name Created
{{ loop.index }} + {{ loop.index }} {% if g.user_session.user_ob %} {{ uc.name }}
+
@@ -90,9 +87,9 @@ - + - + @@ -141,8 +138,8 @@ - - + + - - + + - + @@ -172,6 +172,7 @@ console.time("Creating table"); {% if dataset.type == 'ProbeSet' %} //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters + $('#trait_table').DataTable( { "drawCallback": function( settings ) { $('#trait_table tr').click(function(event) { @@ -182,8 +183,7 @@ $('.trait_checkbox:checkbox').on("change", change_buttons); }, "createdRow": function ( row, data, index ) { - $('td', row).eq(0).attr('style', 'padding-right: 0px;'); - $('td', row).eq(0).attr('align', 'center'); + $('td', row).eq(0).attr('style', 'padding-left: 8px; padding-right: 0px; padding-top: 4px; align: center;'); $('td', row).eq(1).attr('align', 'right'); $('td', row).eq(1).attr('data-export', index+1); $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); @@ -207,15 +207,15 @@ "data": json_trait_list, "columns": [ { "type": "natural", "width": "2%" }, - { "type": "natural", "width": "4%" }, + { "type": "natural", "width": "5%" }, { "type": "natural", "width": "12%" }, { "type": "natural", "width": "12%" }, - { "type": "natural", "width": "25%" }, + { "type": "natural" }, { "type": "natural", "width": "11%" }, + { "type": "natural", "width": "4%" }, { "type": "natural", "width": "5%" }, - { "type": "natural", "width": "6%" }, { "type": "natural", "width": "11%" }, - { "type": "natural", "width": "6%" } + { "type": "natural", "width": "5%" } ], "columnDefs": [ { "targets": 0, @@ -224,8 +224,7 @@ "order": [[1, "asc" ]], buttons: [ { - extend: 'colvis', - text: 'Show or Hide Columns', + extend: 'columnsToggle', columns: ':not(:first-child)', postfixButtons: [ 'colvisRestore' ] } @@ -238,7 +237,8 @@ "scrollY": "600px", "scrollCollapse": false, "scroller": true, - "paging": false + "paging": false, + "orderClasses": true } ); {% elif dataset.type == 'Publish' %} @@ -358,6 +358,7 @@ "paging": false } ); {% endif %} + console.timeEnd("Creating table"); var table = $('#trait_table').DataTable(); -- cgit v1.2.3 From 3c46a58f50f339ec56027db6d2108de5b21d63ac Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 25 Apr 2017 16:52:47 +0000 Subject: Fixed issue with correlation result trait links if target dataset is different from base dataset Improved collection list and view table appearances Added question mark image for glossary entries in table headers Fixed issue where extra decimal place sometimes appeared in bar chart Y axis tick values --- wqflask/runserver.py | 3 ++ .../wqflask/static/new/images/question_mark.jpg | Bin 0 -> 47158 bytes wqflask/wqflask/static/new/javascript/bar_chart.js | 11 ++++++ wqflask/wqflask/templates/collections/list.html | 9 ++++- wqflask/wqflask/templates/collections/view.html | 8 ----- wqflask/wqflask/templates/correlation_page.html | 2 +- wqflask/wqflask/templates/search_result_page.html | 39 +++++++++++---------- 7 files changed, 43 insertions(+), 29 deletions(-) create mode 100644 wqflask/wqflask/static/new/images/question_mark.jpg diff --git a/wqflask/runserver.py b/wqflask/runserver.py index a6ae28af..50805643 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -11,6 +11,9 @@ import logging import utility.logger logger = utility.logger.getLogger(__name__ ) +import signal +signal.signal(signal.SIGPIPE, signal.SIG_DFL) + BLUE = '\033[94m' GREEN = '\033[92m' BOLD = '\033[1m' diff --git a/wqflask/wqflask/static/new/images/question_mark.jpg b/wqflask/wqflask/static/new/images/question_mark.jpg new file mode 100644 index 00000000..82df7e81 Binary files /dev/null and b/wqflask/wqflask/static/new/images/question_mark.jpg differ diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.js b/wqflask/wqflask/static/new/javascript/bar_chart.js index 7ec35148..d8540580 100644 --- a/wqflask/wqflask/static/new/javascript/bar_chart.js +++ b/wqflask/wqflask/static/new/javascript/bar_chart.js @@ -253,6 +253,17 @@ })()) ]); console.log("values: ", values); + + decimal_exists = "False"; + for(i=0; i < values.length; i++){ + if (values[i]['y'] % 1 != 0){ + decimal_exists = "True"; + break; + } + } + if (decimal_exists == "False"){ + _this.chart.yAxis.tickFormat(d3.format('d')) + } d3.select("#bar_chart_container svg").datum([ { values: values diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html index 5a30c98c..b1284895 100644 --- a/wqflask/wqflask/templates/collections/list.html +++ b/wqflask/wqflask/templates/collections/list.html @@ -51,7 +51,7 @@ {% for uc in collections %} - + @@ -89,6 +89,13 @@ {% endif %} - + + - - -{% endblock %} \ No newline at end of file + +{% endblock %} -- cgit v1.2.3 From 02ce39e33fd32b68411ac7b30449507c3f567192 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 16 May 2017 20:00:10 +0000 Subject: Fixed issue that caused mapping to not work for R/qtl Updated dataset menu dropdown info Began adding option to download statistics figures as PNG --- .../marker_regression/marker_regression_gn1.py | 15 +- .../new/javascript/dataset_menu_structure.json | 284 +++++++++++++++++---- .../wqflask/templates/marker_regression_gn1.html | 2 +- wqflask/wqflask/templates/show_trait.html | 1 + .../wqflask/templates/show_trait_statistics.html | 5 +- 5 files changed, 245 insertions(+), 62 deletions(-) diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index 49959a74..82a44796 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -1018,7 +1018,7 @@ class MarkerRegression(object): else: if self.selectedChr > -1: for i, qtlresult in enumerate(self.qtlresults): - if qtlresult['Chr'] != self.selectedChr: + if qtlresult['chr'] != self.selectedChr: continue if i==0 and qtlresult['Mb'] >= Mb: @@ -1027,7 +1027,7 @@ class MarkerRegression(object): #the trait's position is between two traits if i > 0 and self.qtlresults[i-1]['Mb'] < Mb and qtlresult['Mb'] >= Mb: - locPixel = xLeftOffset + plotXScale*(self.qtlresults[i-1]['cM']+(qtlresult['cM']-self.qtlresults[i-1]['cM'])*(Mb - self.qtlresults[i-1]['Mb'])/(qtlresult['Mb']-self.qtlresults[i-1]['Mb'])) + locPixel = xLeftOffset + plotXScale*(self.qtlresults[i-1]['Mb']+(qtlresult['Mb']-self.qtlresults[i-1]['Mb'])*(Mb - self.qtlresults[i-1]['Mb'])/(qtlresult['Mb']-self.qtlresults[i-1]['Mb'])) break #the trait's position is on the right of the last genotype @@ -1036,11 +1036,12 @@ class MarkerRegression(object): else: locPixel = xLeftOffset for i, _chr in enumerate(self.ChrList): - if _chr != Chr: - locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale - else: - locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale - break + if i < (len(self.ChrList)-1): + if _chr != Chr: + locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + else: + locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale + break if locPixel >= 0 and self.plotScale == 'physic': traitPixel = ((locPixel, yZero), (locPixel-6, yZero+12), (locPixel+6, yZero+12)) canvas.drawPolygon(traitPixel, edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json index 861af3d6..f3712b5d 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json +++ b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json @@ -1339,15 +1339,15 @@ "HLC_0311", "GSE9588 Human Liver Normal (Mar11) Both Sexes" ], - [ - "384", - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ], [ "383", "HLCM_0311", "GSE9588 Human Liver Normal (Mar11) Males" + ], + [ + "384", + "HLCF_0311", + "GSE9588 Human Liver Normal (Mar11) Females" ] ], "Phenotypes": [ @@ -1493,6 +1493,15 @@ ] ] }, + "Islets-Gerling": { + "Phenotypes": [ + [ + "None", + "Islets-GerlingPublish", + "Islets-Gerling Published Phenotypes" + ] + ] + }, "TIGEM-Retina-RNA-Seq": { "Phenotypes": [ [ @@ -1560,6 +1569,11 @@ ] ], "Heart mRNA": [ + [ + "820", + "UCLA_AXB_BXA_Aor_Jan16", + "UCLA AXB/BXA Aorta Affy M430 2.0 (Jan16) RMA" + ], [ "421", "IRCM_AXBXA_HRI0213", @@ -1567,6 +1581,11 @@ ] ], "Liver mRNA": [ + [ + "822", + "UCLA_AXB_BXA_Liv_Jan16", + "UCLA AXB/BXA Liver Affy M430 2.0 (Jan16) RMA" + ], [ "352", "GSE16780AB_UCLA_ML0911", @@ -1726,11 +1745,6 @@ ] ], "Striatum mRNA": [ - [ - "85", - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ], [ "84", "SA_M2_0905_R", @@ -1740,21 +1754,26 @@ "83", "SA_M2_0905_M", "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" + ], + [ + "85", + "SA_M2_0905_P", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" ] ] }, "BHF2": { "Adipose mRNA": [ - [ - "197", - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], [ "196", "UCLA_BHF2_ADIPOSE_MALE", "UCLA BHF2 Adipose Male mlratio" ], + [ + "197", + "UCLA_BHF2_ADIPOSE_FEMALE", + "UCLA BHF2 Adipose Female mlratio" + ], [ "165", "UCLA_BHF2_ADIPOSE_0605", @@ -1762,16 +1781,16 @@ ] ], "Brain mRNA": [ - [ - "199", - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], [ "198", "UCLA_BHF2_BRAIN_MALE", "UCLA BHF2 Brain Male mlratio" ], + [ + "199", + "UCLA_BHF2_BRAIN_FEMALE", + "UCLA BHF2 Brain Female mlratio" + ], [ "166", "UCLA_BHF2_BRAIN_0605", @@ -1786,16 +1805,16 @@ ] ], "Liver mRNA": [ - [ - "201", - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], [ "200", "UCLA_BHF2_LIVER_MALE", "UCLA BHF2 Liver Male mlratio" ], + [ + "201", + "UCLA_BHF2_LIVER_FEMALE", + "UCLA BHF2 Liver Female mlratio" + ], [ "167", "UCLA_BHF2_LIVER_0605", @@ -1999,11 +2018,6 @@ "BR_U_1105_P", "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" ], - [ - "81", - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], [ "80", "BR_U_0805_M", @@ -2014,6 +2028,11 @@ "BR_U_0805_R", "UTHSC Brain mRNA U74Av2 (Aug05) RMA" ], + [ + "81", + "BR_U_0805_P", + "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" + ], [ "42", "CB_M_0204_P", @@ -2142,6 +2161,13 @@ "BXD Genotypes" ] ], + "Heart mRNA": [ + [ + "819", + "UCLA_BXD_Aor_Jan16", + "UCLA BXD Aorta Affy M430 2.0 (Jan16) RMA" + ] + ], "Hematopoietic Cells mRNA": [ [ "149", @@ -2217,6 +2243,26 @@ "UMUTAffyExon_0209_RMA", "UMUTAffy Hippocampus Exon (Feb09) RMA" ], + [ + "814", + "UTHSC_ILM_BXD_hipp_NOSb_0217", + "UTHSC BXD Hippocampus ILM v6.1 NOS Balanced (Feb17) RankInv" + ], + [ + "815", + "UTHSC_ILM_BXD_hipp_NOEb_0217", + "UTHSC BXD Hippocampus ILM v6.1 NOE Balanced (Feb17) RankInv" + ], + [ + "816", + "UTHSC_ILM_BXD_hipp_RSSb_0217", + "UTHSC BXD Hippocampus ILM v6.1 RSS Balanced (Feb17) RankInv" + ], + [ + "817", + "UTHSC_ILM_BXD_hipp_RSEb_0217", + "UTHSC BXD Hippocampus ILM v6.1 RSE Balanced (Feb17) RankInv" + ], [ "780", "UTHSC_ILM_BXD_hipp_NOEb_0216", @@ -2390,15 +2436,25 @@ ] ], "Liver Proteome": [ + [ + "540", + "EPFLETHZBXDprotCD0514", + "EPFL/ETHZ BXD Liver, Chow Diet (Jun16) Top100 SWATH" + ], + [ + "541", + "EPFLETHZBXDprotHFD0514", + "EPFL/ETHZ BXD Liver, High Fat Diet (Jun16) Top100 SWATH" + ], [ "704", "EPFLETHZBXDprotCD_LS1114", - "EPFL/ETHZ BXD Liver, Chow Diet (Oct14) Light SWATH" + "EPFL/ETHZ BXD Liver, Chow Diet (Oct14) Top10 SWATH" ], [ "705", "EPFLETHZBXDprotHF_LS1114", - "EPFL/ETHZ BXD Liver, High Fat Diet (Oct14) Light SWATH" + "EPFL/ETHZ BXD Liver, High Fat Diet Diet (Oct14) Top10 SWATH" ], [ "703", @@ -2414,19 +2470,14 @@ "489", "EPFLBXDprotHFDRPN0214", "EPFL/LISP BXD Liver, Soluble Proteins HFD (Feb14) SRM" - ], - [ - "540", - "EPFLETHZBXDprotCD0514", - "EPFL/ETHZ BXD Liver, Soluble Proteins CD (Jun14) SWATH" - ], - [ - "541", - "EPFLETHZBXDprotHFD0514", - "EPFL/ETHZ BXD Liver, Soluble Proteins HFD (Jun14) SWATH" ] ], "Liver mRNA": [ + [ + "818", + "UCLA_BXD_Liv_Jan16", + "UCLA BXD Liver Affy M430 2.0 (Jan16) RMA" + ], [ "430", "EPFLMouseLiverRMA0413", @@ -2442,6 +2493,11 @@ "EPFLMouseLiverCDRMA0413", "EPFL/LISP BXD CD Liver Affy Mouse Gene 1.0 ST (Apr13) RMA" ], + [ + "433", + "EPFLMouseLiverBothExRMA0413", + "EPFL/LISP BXD CD+HFD Liver Affy Mouse Gene 1.0 ST (Apr13) RMA Exon Level" + ], [ "700", "UTHSC-VGX_MmBXDHepatocytesRMA1014", @@ -2466,6 +2522,51 @@ "702", "SUH_Liv_RMAEx_0611", "SUH BXD Liver CCl4-treated Affy Mouse Gene 1.0 ST Exon Level (Jun11) RMA" + ], + [ + "256", + "GenEx_BXD_liverEt_M5_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Both Sexes" + ], + [ + "257", + "GenEx_BXD_liverEt_M5M_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Males" + ], + [ + "258", + "GenEx_BXD_liverEt_M5F_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Females" + ], + [ + "307", + "GenEx_BXD_liverEt_RMA_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes" + ], + [ + "308", + "GenEx_BXD_liverEt_RMA_M_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males" + ], + [ + "309", + "GenEx_BXD_liverEt_RMA_F_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females" + ], + [ + "310", + "GenEx_BXD_liverSal_RMA_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes" + ], + [ + "311", + "GenEx_BXD_liverSal_RMA_M_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males" + ], + [ + "312", + "GenEx_BXD_liverSal_RMA_F_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females" ] ], "Lung mRNA": [ @@ -2545,15 +2646,15 @@ "HQFNeoc_0208_RankInv", "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" ], - [ - "275", - "DevNeocortex_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv" - ], [ "274", "DevNeocortex_ILM6.2P3RInv_1110", "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv" + ], + [ + "275", + "DevNeocortex_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv" ] ], "Nucleus Accumbens mRNA": [ @@ -2760,11 +2861,6 @@ ] ], "Ventral Tegmental Area mRNA": [ - [ - "230", - "VCUEtvsSal_0609_R", - "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) RMA" - ], [ "229", "VCUEtOH_0609_R", @@ -2774,6 +2870,11 @@ "228", "VCUSal_0609_R", "VCU BXD VTA Sal M430 2.0 (Jun09) RMA" + ], + [ + "230", + "VCUEtvsSal_0609_R", + "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) RMA" ] ] }, @@ -2920,6 +3021,27 @@ ] ] }, + "CIE-RMA": { + "Midbrain mRNA": [ + [ + "830", + "INIA_UTHSC_Mid_AffyMTA1_Apr17", + "INIA-UTHSC Midbrain CIE Affy MTA 1.0 GeneLevel (Apr17) RMA" + ], + [ + "834", + "INIA_UTHSC_Mid_AffyMTA1_Ex_May17", + "INIA-UTHSC Midbrain CIE Affy MTA 1.0 Exon Level (Apr17) RMA" + ] + ], + "Phenotypes": [ + [ + "None", + "CIE-RMAPublish", + "CIE-RMA Published Phenotypes" + ] + ] + }, "CMS": { "Phenotypes": [ [ @@ -3021,6 +3143,13 @@ "CXB Genotypes" ] ], + "Heart mRNA": [ + [ + "821", + "UCLA_CXB_Aor_Jan16", + "UCLA CXB Aorta Affy M430 2.0 (Jan16) RMA" + ] + ], "Hippocampus mRNA": [ [ "100", @@ -3033,6 +3162,13 @@ "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" ] ], + "Liver mRNA": [ + [ + "823", + "UCLA_CXB_Liv_Jan16", + "UCLA CXB Liver Affy M430 2.0 (Jan16) RMA" + ] + ], "Phenotypes": [ [ "628", @@ -3048,6 +3184,7 @@ ] ] }, + "EMSR": {}, "HS": { "Hippocampus mRNA": [ [ @@ -3544,6 +3681,10 @@ "HSB", "Brain, Development: Normal Gene Expression (Yale/Sestan)" ], + [ + "Islets-Gerling", + "Pancreatic: Islets (UTHSC/Gerling)" + ], [ "TIGEM-Retina-RNA-Seq", "Retina: Normal Adult Gene Expression, RNA-Seq (TIGEM)" @@ -3616,7 +3757,11 @@ ], [ "CIE-INIA", - "Chronic Intermittent Ethanol" + "Chronic Intermittent Ethanol Phase 1" + ], + [ + "CIE-RMA", + "Chronic Intermittent Ethanol Phase 2" ], [ "CMS", @@ -3630,6 +3775,10 @@ "CXB", "CXB" ], + [ + "EMSR", + "Ethanol-Medicated Stress Reduction" + ], [ "HS", "Heterogeneous Stock" @@ -4414,6 +4563,12 @@ "Ventrolateral Prefrontal Cortex mRNA" ] ], + "Islets-Gerling": [ + [ + "Phenotypes", + "Phenotypes" + ] + ], "TIGEM-Retina-RNA-Seq": [ [ "Phenotypes", @@ -4629,6 +4784,10 @@ "Gastrointestinal mRNA", "Gastrointestinal mRNA" ], + [ + "Heart mRNA", + "Heart mRNA" + ], [ "Hematopoietic Cells mRNA", "Hematopoietic Cells mRNA" @@ -4780,6 +4939,16 @@ "LCM Brain Regions mRNA" ] ], + "CIE-RMA": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Midbrain mRNA", + "Midbrain mRNA" + ] + ], "CMS": [ [ "Phenotypes", @@ -4821,15 +4990,24 @@ "Genotypes", "Genotypes" ], + [ + "Heart mRNA", + "Heart mRNA" + ], [ "Hippocampus mRNA", "Hippocampus mRNA" ], + [ + "Liver mRNA", + "Liver mRNA" + ], [ "Spleen mRNA", "Spleen mRNA" ] ], + "EMSR": [], "HS": [ [ "Phenotypes", diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/marker_regression_gn1.html index 4cea51b2..65debd10 100644 --- a/wqflask/wqflask/templates/marker_regression_gn1.html +++ b/wqflask/wqflask/templates/marker_regression_gn1.html @@ -14,7 +14,7 @@ - {% if mapping_method == "reaper" %} + {% if mapping_method == "reaper" or mapping_method == "rqtl_geno" %} {% endif %} diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 56b6cc62..5a880647 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -129,6 +129,7 @@ + diff --git a/wqflask/wqflask/templates/show_trait_statistics.html b/wqflask/wqflask/templates/show_trait_statistics.html index 0a0e9990..ac44b656 100644 --- a/wqflask/wqflask/templates/show_trait_statistics.html +++ b/wqflask/wqflask/templates/show_trait_statistics.html @@ -94,12 +94,15 @@
{% if sample_groups|length != 1 %} + Select Group: -

+ +
+
{% endif %}
-- cgit v1.2.3 From 8677d1b7bd5b32791c440bf0de2fc4c61c98299f Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Sun, 21 May 2017 07:21:44 +0000 Subject: Merge from the diet branch. * refactored ./bin/genenetwork2 and /etc/default_settings - better detection of Guix - removed unused parameters, such as GEMMA_RESULT_PATH and TEMP_TRAITS - removing some default settings, such as PYLMM_COMMAND - rename some settings, such as SQL_URI and LOG_SQL_ALCHEMY - added GUIX_JS_PATH for JS modules * Added documentation on installing binary GN2 * Updated Twitter board to latest version in Guix - it had broken * Updated many tools in the latest Guix profile --- bin/genenetwork2 | 104 ++--- doc/GUIX-Reproducible-from-source.org | 356 ++++++++++++++++- doc/README.org | 440 +++++---------------- doc/development.org | 23 ++ etc/VERSION | 1 + etc/default_settings.py | 33 +- test/lib/main_web_functionality.rb | 4 + wqflask/base/webqtlConfig.py | 2 +- wqflask/maintenance/gen_select_dataset.py | 2 +- wqflask/utility/tools.py | 11 +- wqflask/wqflask/database.py | 2 +- .../wqflask/marker_regression/marker_regression.py | 2 +- wqflask/wqflask/templates/base.html | 2 +- wqflask/wqflask/templates/error.html | 4 +- wqflask/wqflask/user_manager.py | 26 +- wqflask/wqflask/views.py | 5 +- 16 files changed, 586 insertions(+), 431 deletions(-) create mode 100644 doc/development.org create mode 100644 etc/VERSION diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 52d3155c..df688989 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -1,34 +1,39 @@ #! /bin/bash # # This will run the GN2 server (with default settings if none -# supplied). Pass in your own settings file, e.g. +# supplied). Typically you need a GNU Guix profile which is set with +# an environment variable (this profile is dictated by the +# installation path of genenetwork). Say your profile is in +# ~/opt/gn-latest-guix # -# ./bin/genenetwork2 ~/my_settings.py +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 # -# But better is to retain the defaults and override them with -# JSON file (see the deploy docs). +# You can pass in your own settings file, e.g. # -# ./bin/genenetwork2 ~/my_overrides.json +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ~/my_settings.py # # To run a maintenance script with settings (instead of the webserver) add that with # a -c switch, e.g. # -# ./bin/genenetwork2 ~/my_overrides.json -c ./wqflask/maintenance/gen_select_dataset.py -# -# Environment settings can be used to preconfigure as well as a -# settings.py file. -# -# GN2_BASE_PATH is base directory of wqflask source code -# +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ~/my_overrides.json -c ./wqflask/maintenance/gen_select_dataset.py SCRIPT=$(readlink -f "$0") GN2_BASE_DIR=$(dirname $(dirname "$SCRIPT")) +GN2_ID=$(cat /etc/hostname):$(basename $GN2_BASE_DIR) echo GN2_BASE_DIR=$GN2_BASE_DIR -GIT_HASH=$(git rev-parse HEAD) -GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -export GN_VERSION=$(cat $GN2_BASE_DIR/VERSION)-$GIT_BRANCH-${GIT_HASH:0:9} +GUIX_SITE=$GN2_BASE_DIR/lib/python2.7/site-packages +if [ -d $GUIX_SITE ]; then + echo INFO: GN2 is running from GNU Guix + GN2_BASE_DIR=$GUIX_SITE + export GN_VERSION=$GN2_ID:$(cat $GN2_BASE_DIR/etc/VERSION) +else + echo INFO: GN2 is running from a source tree + GIT_HASH=$(git rev-parse HEAD) + GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + export GN_VERSION=$GN2_ID:$(cat $GN2_BASE_DIR/etc/VERSION)-$GIT_BRANCH-${GIT_HASH:0:9} +fi echo GN_VERSION=$GN_VERSION # Handle settings parameter (can be .py or .json) @@ -41,13 +46,8 @@ else shift fi if [ ! -e $settings ]; then - GUIX_ETC=$GN2_BASE_DIR/lib/python2.7/site-packages/genenetwork2-2.0-py2.7.egg - if [ -d $GUIX_ETC ]; then - echo INFO: GN2 is actually running from GNU Guix - else - echo "ERROR: can not locate settings file - pass it in the command line" - exit 1 - fi + echo "ERROR: can not locate settings file - pass it in the command line" + exit 1 fi export WQFLASK_SETTINGS=$settings # Python export WQFLASK_OVERRIDES=$overrides # JSON @@ -55,30 +55,40 @@ export WQFLASK_OVERRIDES=$overrides # JSON echo WQFLASK_SETTINGS=$settings echo WQFLASK_OVERRIDES=$overrides -# ---- Checks and balances -if [ -z $GUIX_ETC ]; then - if [ -z $GN2_PROFILE ] ; then - echo "WARNING: GN2_PROFILE has not been set - I hope you know what you are doing!" - else - export PATH=$GN2_PROFILE/bin:$PATH - export PYTHONPATH=$GN2_PROFILE/lib/python2.7/site-packages - export R_LIBS_SITE=$GN2_PROFILE/site-library - export GUIX_GTK3_PATH="$GN2_PROFILE/lib/gtk-3.0" - export GI_TYPELIB_PATH="$GN2_PROFILE/lib/girepository-1.0" - export XDG_DATA_DIRS="$GN2_PROFILE/share" - export GIO_EXTRA_MODULES="$GN2_PROFILE/lib/gio/modules" - export LC_ALL=C - fi - if [ -z $PYTHONPATH ] ; then - echo "WARNING PYTHONPATH has not been set - use GN2_PROFILE!" - fi - if [ ! -d $R_LIBS_SITE ] ; then - echo "ERROR: R_LIBS_SITE has not been set correctly (we only allow one path) - use GN2_PROFILE!" - echo "Paste into your shell the output of (for example)" - echo "guix package -p \$GN2_PROFILE --search-paths" - exit 1 +if [ -z $GN2_PROFILE ] ; then + echo "WARNING: GN2_PROFILE has not been set - you need the environment, so I hope you know what you are doing!" + export GN2_PROFILE=$(dirname $(dirname $(which genenetwork2))) + if [ -d $GN2_PROFILE ]; then + echo "Best guess is $GN2_PROFILE" fi fi +if [ -z $GN2_PROFILE ]; then + read -p "PRESS [ENTER] TO CONTINUE..." +else + export PATH=$GN2_PROFILE/bin:$PATH + export PYTHONPATH=$GN2_PROFILE/lib/python2.7/site-packages + export R_LIBS_SITE=$GN2_PROFILE/site-library + export GUIX_JS_PATH=$GN2_PROFILE/share/genenetwork2/javascript + export GUIX_GTK3_PATH="$GN2_PROFILE/lib/gtk-3.0" + export GI_TYPELIB_PATH="$GN2_PROFILE/lib/girepository-1.0" + export XDG_DATA_DIRS="$GN2_PROFILE/share" + export GIO_EXTRA_MODULES="$GN2_PROFILE/lib/gio/modules" + export LC_ALL=C # FIXME + export GENENETWORK_FILES="$GN2_PROFILE/share/genenetwork2" + export PLINK_COMMAND="$GN2_PROFILE/bin/plink2" + export PYLMM_COMMAND="$GN2_PROFILE/bin/pylmm_redis" + export GEMMA_COMMAND="$GN2_PROFILE/bin/gemma" +fi +if [ -z $PYTHONPATH ] ; then + echo "ERROR PYTHONPATH has not been set - use GN2_PROFILE!" + exit 1 +fi +if [ ! -d $R_LIBS_SITE ] ; then + echo "ERROR R_LIBS_SITE has not been set correctly (we only allow one path) - use GN2_PROFILE!" + echo "Paste into your shell the output of (for example)" + echo "guix package -p \$GN2_PROFILE --search-paths" + exit 1 +fi # We may change this one: export PYTHONPATH=$GN2_BASE_DIR/wqflask:$PYTHONPATH @@ -88,6 +98,8 @@ if [ -z $TMPDIR ]; then TMPDIR="/tmp" fi +# Show environment settings +set|grep guix set|grep $GN2_PROFILE set|grep TMPDIR @@ -97,7 +109,7 @@ if [ "$1" = '-c' ] ; then cmd=${2#wqflask/} echo PYTHONPATH=$PYTHONPATH echo RUNNING COMMAND $cmd - /usr/bin/env python $cmd + python $cmd exit 0 fi @@ -109,4 +121,4 @@ dbfilename gn2.rdb # Start the flask server running GN2 cd $GN2_BASE_DIR/wqflask echo "Starting with $settings" -/usr/bin/env python runserver.py +python runserver.py diff --git a/doc/GUIX-Reproducible-from-source.org b/doc/GUIX-Reproducible-from-source.org index 4399ea26..83adce99 100644 --- a/doc/GUIX-Reproducible-from-source.org +++ b/doc/GUIX-Reproducible-from-source.org @@ -2,19 +2,188 @@ * Table of Contents :TOC: - [[#introduction][Introduction]] - - [[#binary-deployment][Binary deployment]] + - [[#binary-deployment-through-gnu-guix][Binary deployment through GNU Guix]] + - [[#quick-installation-recipe][Quick installation recipe]] + - [[#step-1-install-gnu-guix][Step 1: Install GNU Guix]] + - [[#step-2-checkout-the-gn2-git-repositories][Step 2: Checkout the GN2 git repositories]] + - [[#step-3-authorize-the-gn-guix-server][Step 3: Authorize the GN Guix server]] + - [[#step-4-install-and-run-gn2][Step 4: Install and run GN2]] - [[#from-source-deployment][From source deployment]] - [[#create-archive][Create archive]] + - [[#source-deployment][Source deployment]] + - [[#run-your-own-copy-of-gn2][Run your own copy of GN2]] + - [[#set-up-nginx-port-forwarding][Set up nginx port forwarding]] + - [[#source-deployment-and-other-information-on-reproducibility][Source deployment and other information on reproducibility]] + - [[#update-to-recent-guix][Update to recent guix]] + - [[#install-gn2][Install GN2]] + - [[#run-gn2][Run GN2]] * Introduction Large system deployments tend to get very complex. In this document we explain the GeneNetwork deployment system which is based on GNU Guix -(see Pjotr's [[https://github.com/pjotrp/guix-notes/blob/master/README.md][Guix-notes]]). +(see Pjotr's [[https://github.com/pjotrp/guix-notes/blob/master/README.md][Guix-notes]] and the main [[README.org]] doc). -* Binary deployment +* Binary deployment through GNU Guix +** Quick installation recipe -NYA (will go to README) +This is a recipe for quick and dirty installation of GN2. For +convenience everything is installed as root, though in reality only +GNU Guix has to be installed as root. I tested this recipe on a fresh +install of Debian 8.3.0 (in KVM) though it should work on any modern +Linux distribution (including CentOS). + + +Note that GN2 consists of an approx. 5 GB installation including +database. If you use a virtual machine we recommend to use at least +double. + +** Step 1: Install GNU Guix + +Fetch the GNU Guix binary from [[https://www.gnu.org/software/guix/download/][here]] (middle panel) and follow +[[https://www.gnu.org/software/guix/manual/html_node/Binary-Installation.html][instructions]]. Essentially, download and unpack the tar ball (which +creates directories in /gnu and /var/guix), add build users and group +(Guix builds software as unpriviliged users) and run the Guix daemon +after fixing the paths (also known as the 'profile'). + +Once you have succeeded, you have to [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#set-the-key][set the key]] (getting permission +to download binaries from the GNU server) and you should be able to +install the hello package using binary packages (no building) + +#+begin_src bash +export PATH=~/.guix-profile/bin:$PATH +guix pull +guix package -i hello --dry-run +#+end_src + +Which should show something like + +: The following files would be downloaded: +: /gnu/store/zby49aqfbd9w9br4l52mvb3y6f9vfv22-hello-2.10 +: ... +#+end_src + +means binary installs. The actual installation command of 'hello' is + +#+begin_src bash +guix package -i hello +hello + Hello, world! +#+end_src + +If you actually see things building it means that Guix is not yet +properly installed and up-to-date, i.e., the key is missing or you +need to do a 'guix pull'. Press Ctrl-C to interrupt. + +If you need more help we have another writeup in [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#binary-installation][guix-notes]]. To get +rid of the locale warning see [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#set-locale][set-locale]]. + +** Step 2: Checkout the GN2 git repositories + +To fixate the software dependency graph GN2 uses git repositories of +Guix packages. First install git if it is missing + +#+begin_src bash +guix package -i git +export GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt +#+end_src + +check out the git repositories (gn-deploy branch) + +#+begin_src bash +cd ~ +mkdir genenetwork +cd genenetwork +git clone --branch gn-deploy https://github.com/genenetwork/guix-bioinformatics +git clone --branch gn-deploy --recursive https://github.com/genenetwork/guix guix-gn-deploy +cd guix-gn-deploy +#+end_src bash + +To test whether this is working try: + +#+begin_src bash +#+end_src bash + +** Step 3: Authorize the GN Guix server + +GN2 has its own GNU Guix binary distribution server. To trust it you have +to add the following key + +#+begin_src scheme +(public-key + (ecc + (curve Ed25519) + (q #11217788B41ADC8D5B8E71BD87EF699C65312EC387752899FE9C888856F5C769#) + ) +) +#+end_src + +by pasting it into the command + +#+begin_src bash +guix archive --authorize +#+end_src + +and hit Ctrl-D. + +Now you can use the substitute server to install GN2 binaries. + +** Step 4: Install and run GN2 + +Since this is a quick and dirty install we are going to override the +GNU Guix package path by pointing the package path to our repository: + +#+begin_src bash +rm /root/.config/guix/latest +ln -s ~/genenetwork/guix-gn-deploy/ /root/.config/guix/latest +#+end_src + +Now check whether you can find the GN2 package with + +#+begin_src bash +env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ guix package -A genenetwork2 + genenetwork2 2.0-a8fcff4 out gn/packages/genenetwork.scm:144:2 +#+end_src + +(ignore the source file newer then ... messages, this is caused by the +/root/.config/guix/latest override). + +And install with + +#+begin_src bash +env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ \ + guix package -i genenetwork2 \ + --substitute-urls="http://guix.genenetwork.org" +#+end_src + +Note: the order of the substitute url's may make a difference in speed +(put the one first that is fastest for your location and time of day). + +Note: if your system starts building or gives an error it may well be +Step 3 did not succeed. The installation should actually be smooth at +this point and only do binary installs (no compiling). + +After installation you should be able to run genenetwork2 after updating +the Guix suggested environment vars. Check the output of + +#+begin_src bash +guix package --search-paths +export PYTHONPATH="/root/.guix-profile/lib/python2.7/site-packages" +export R_LIBS_SITE="/root/.guix-profile/site-library/" +#+end_src + +and copy-paste the listed exports into the terminal before running: + +#+begin_src bash +genenetwork2 +#+end_src + +It will complain that the database is missing. See the next section on +running MySQL server for downloading and installing a MySQL GN2 +database. After installing the database restart genenetwork2 and point +your browser at [[http://localhost:5003/]]. + +End of the GN2 installation recipe! * From source deployment @@ -52,3 +221,182 @@ gn-stable-guix$ env GUIX_PACKAGE_PATH=../guix-bioinformatics ./pre-inst-env guix * Create archive : env GUIX_PACKAGE_PATH=../../genenetwork/guix-bioinformatics/ ./pre-inst-env guix archive --export -r genenetwork2 > guix_gn2-2.0-9e9475053.nar + + +* Source deployment + +This section gives a more elaborate instruction for installing GN2 +from source. + +First execute above 4 steps: + + - [[#step-1-install-gnu-guix][Step 1: Install GNU Guix]] + - [[#step-2-checkout-the-gn2-git-repositories][Step 2: Checkout the GN2 git repositories]] + - [[#step-3-authorize-the-gn-guix-server][Step 3: Authorize the GN Guix server]] + - [[#step-4-install-and-run-gn2-][Step 4: Install and run GN2 ]] + + +** Run your own copy of GN2 + +At some point you may want to fix the source code. Assuming you have +Guix and Genenetwork2 installed (as described above) clone the GN2 +repository from https://github.com/genenetwork/genenetwork2. + +Copy-paste the paths into your terminal (mainly so PYTHON_PATH and +R_LIBS_SITE are set) from the information given by guix: + +: guix package --search-paths + +Inside the repository: + +: cd genenetwork2 +: ./bin/genenetwork2 + +Will fire up your local repo http://localhost:5003/ using the +settings in ./etc/default_settings.py. These settings may +not reflect your system. To override settings create your own from a copy of +default_settings.py and pass it into GN2 with + +: ./bin/genenetwork2 $HOME/my_settings.py + +and everything *should* work (note the full path to the settings +file). This way we develop against the exact same dependency graph of +software. + +If something is not working, take a hint from the settings file +that comes in the Guix installation. It sits in something like + +: cat ~/.guix-profile/lib/python2.7/site-packages/genenetwork2-2.0-py2.7.egg/etc/default_settings.py + +** Set up nginx port forwarding + +nginx can be used as a reverse proxy for GN2. For example, we want to +expose GN2 on port 80 while it is running on port 5003. Essentially +the configuration looks like + +#+begin_src js + server { + listen 80; + server_name test-gn2.genenetwork.org; + access_log logs/test-gn2.access.log; + + proxy_connect_timeout 3000; + proxy_send_timeout 3000; + proxy_read_timeout 3000; + send_timeout 3000; + + location / { + proxy_set_header Host $http_host; + proxy_set_header Connection keep-alive; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_pass http://127.0.0.1:5003; + } +} +#+end_src js + +Install the nginx webserver (as root) + +: guix package -i nginx + +The nginx example configuration examples can be found in the Guix +store through + +: ls -l /root/.guix-profile/sbin/nginx +: lrwxrwxrwx 3 root guixbuild 66 Dec 31 1969 /root/.guix-profile/sbin/nginx -> /gnu/store/g0wrcl5z27rmk5b52rldzvk1bzzbnz2l-nginx-1.8.1/sbin/nginx + +Use that path + +: ls /gnu/store/g0wrcl5z27rmk5b52rldzvk1bzzbnz2l-nginx-1.8.1/share/nginx/conf/ +: fastcgi.conf koi-win scgi_params +: fastcgi.conf.default mime.types scgi_params.default +: fastcgi_params mime.types.default uwsgi_params +: fastcgi_params.default nginx.conf uwsgi_params.default +: koi-utf nginx.conf.default win-utf + +And copy any relevant files to /etc/nginx. A configuration file for +GeneNetwork (reverse proxy) port forwarding can be found in the source +repository under ./etc/nginx-genenetwork.conf. Copy this file to /etc +(still as root) +: cp ./etc/nginx-genenetwork.conf /etc/nginx/ + +Make dirs + +: mkdir -p /var/spool/nginx/logs + +Add users + +: adduser nobody ; addgroup nobody + +Run nginx + +: /root/.guix-profile/sbin/nginx -c /etc/nginx/nginx-genenetwork.conf -p /var/spool/nginx + +* Source deployment and other information on reproducibility + +See the document [[GUIX-Reproducible-from-source.org]]. + +** Update to recent guix + +We now compile Guix from scratch. + +Create, install and run a recent version of the guix-daemon by +compiling the guix repository you have installed with git in +step 2. Follow [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#building-gnu-guix-from-source-using-guix][these]] steps carefully after + +: cd ~/genenetwork/guix-gn-deploy + +Make sure to restart the guix daemon and run guix client from this +directory. + +** Install GN2 + +Reinstall genenetwork2 using the new tree + +#+begin_src bash +env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ ./pre-inst-env guix package -i genenetwork2 --substitute-urls="http://guix.genenetwork.org https://mirror.guixsd.org" +#+end_src bash + +Note the use of ./pre-inst-env here! + +Actually, it should be the same installation as in step 4, so nothing +gets downloaded. + +** Run GN2 + +Make a note of the paths with + +#+begin_src bash +./pre-inst-env guix package --search-paths +#+end_src bash + +or this should also work if guix is installed + +#+begin_src bash +guix package --search-paths +#+end_src bash + +After setting the paths for the server + +#+begin_src bash +export PATH=~/.guix-profile/bin:$PATH +export PYTHONPATH="$HOME/.guix-profile/lib/python2.7/site-packages" +export R_LIBS_SITE="$HOME/.guix-profile/site-library/" +export GUIX_GTK3_PATH="$HOME/.guix-profile/lib/gtk-3.0" +export GI_TYPELIB_PATH="$HOME/.guix-profile/lib/girepository-1.0" +export XDG_DATA_DIRS="$HOME/.guix-profile/share" +export GIO_EXTRA_MODULES="$HOME/.guix-profile/lib/gio/modules" +#+end_src bash + +run the main script (in ~/.guix-profile/bin) + +#+begin_src bash +genenetwork2 +#+end_src bash + +will start the default server which listens on port 5003, i.e., +http://localhost:5003/. + +OK, we are where we were before with step 4. Only difference is that we +used our own compiled guix server. diff --git a/doc/README.org b/doc/README.org index b38ea664..a39ef603 100644 --- a/doc/README.org +++ b/doc/README.org @@ -2,33 +2,27 @@ * Table of Contents :TOC: - [[#introduction][Introduction]] - - [[#quick-installation-recipe][Quick installation recipe]] - - [[#step-1-install-gnu-guix][Step 1: Install GNU Guix]] - - [[#step-2-checkout-the-gn2-git-repositories][Step 2: Checkout the GN2 git repositories]] - - [[#step-3-authorize-the-gn-guix-server][Step 3: Authorize the GN Guix server]] - - [[#step-4-install-and-run-gn2][Step 4: Install and run GN2]] + - [[#install][Install]] + - [[#tarball][Tarball]] + - [[#docker][Docker]] + - [[#with-source][With source]] + - [[#running-gn2][Running GN2]] - [[#run-mysql-server][Run MySQL server]] + - [[#install-mysql-with-gnu-guix][Install MySQL with GNU GUIx]] + - [[#load-the-small-database-in-mysql][Load the small database in MySQL]] - [[#gn2-dependency-graph][GN2 Dependency Graph]] - - [[#source-deployment][Source deployment]] - - [[#run-your-own-copy-of-gn2][Run your own copy of GN2]] - - [[#set-up-nginx-port-forwarding][Set up nginx port forwarding]] - - [[#source-deployment-and-other-information-on-reproducibility][Source deployment and other information on reproducibility]] - - [[#update-to-recent-guix][Update to recent guix]] - - [[#install-gn2][Install GN2]] - - [[#run-gn2][Run GN2]] + - [[#working-with-the-gn2-source-code][Working with the GN2 source code]] - [[#trouble-shooting][Trouble shooting]] - [[#importerror-no-module-named-jinja2][ImportError: No module named jinja2]] - [[#error-can-not-find-directory-homegn2_data][ERROR: can not find directory $HOME/gn2_data]] - [[#cant-run-a-module][Can't run a module]] - [[#rpy2-error-show-now-found][Rpy2 error 'show' now found]] + - [[#mysql-cant-connect-server-through-socket-error][Mysql can't connect server through socket ERROR]] + - [[#read-more][Read more]] - [[#irc-session][IRC session]] * Introduction -If you want to understand the architecture of GN2 read -[[Architecture.org]]. The rest of this document is mostly on deployment -of GN2. - Large system deployments can get very [[http://biogems.info/contrib/genenetwork/gn2.svg ][complex]]. In this document we explain the GeneNetwork version 2 (GN2) reproducible deployment system which is based on GNU Guix (see also [[https://github.com/pjotrp/guix-notes/blob/master/README.md][Guix-notes]]). The Guix @@ -37,195 +31,113 @@ system can be used to install GN with all its files and dependencies. The official installation path is from a checked out version of the main Guix package tree and that of the Genenetwork package tree. Current supported versions can be found as the SHA values of -'gn-latest' branches of [[https://github.com/genenetwork/guix-bioinformatics/tree/gn-latest][Guix bioinformatics]] and [[https://github.com/genenetwork/guix/tree/gn-latest][GNU Guix main]]. +'gn-latest' branches of [[https://gitlab.com/genenetwork/guix-bioinformatics][Guix bioinformatics]] and [[https://gitlab.com/genenetwork/guix][GNU Guix]]. For a full view of runtime dependencies as defined by GNU Guix, see -the [[#gn2-dependency-graph][GN2 Dependency Graph]]. - -* Quick installation recipe - -This is a recipe for quick and dirty installation of GN2. For -convenience everything is installed as root, though in reality only -GNU Guix has to be installed as root. I tested this recipe on a fresh -install of Debian 8.3.0 (in KVM) though it should work on any modern -Linux distribution (including CentOS). For more elaborate installation -instructions see [[#source-deployment][Source deployment]]. - -Note that GN2 consists of an approx. 5 GB installation including -database. If you use a virtual machine we recommend to use at least -double. - -** Step 1: Install GNU Guix - -Fetch the GNU Guix binary from [[https://www.gnu.org/software/guix/download/][here]] (middle panel) and follow -[[https://www.gnu.org/software/guix/manual/html_node/Binary-Installation.html][instructions]]. Essentially, download and unpack the tar ball (which -creates directories in /gnu and /var/guix), add build users and group -(Guix builds software as unpriviliged users) and run the Guix daemon -after fixing the paths (also known as the 'profile'). - -Once you have succeeded, you have to [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#set-the-key][set the key]] (getting permission -to download binaries from the GNU server) and you should be able to -install the hello package using binary packages (no building) - -#+begin_src bash -export PATH=~/.guix-profile/bin:$PATH -guix pull -guix package -i hello --dry-run -#+end_src - -Which should show something like - -: The following files would be downloaded: -: /gnu/store/zby49aqfbd9w9br4l52mvb3y6f9vfv22-hello-2.10 -: ... -#+end_src - -means binary installs. The actual installation command of 'hello' is - -#+begin_src bash -guix package -i hello -hello - Hello, world! -#+end_src - -If you actually see things building it means that Guix is not yet -properly installed and up-to-date, i.e., the key is missing or you -need to do a 'guix pull'. Press Ctrl-C to interrupt. - -If you need more help we have another writeup in [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#binary-installation][guix-notes]]. To get -rid of the locale warning see [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#set-locale][set-locale]]. - -** Step 2: Checkout the GN2 git repositories +an example of the [[#gn2-dependency-graph][GN2 Dependency Graph]]. -To fixate the software dependency graph GN2 uses git repositories of -Guix packages. First install git if it is missing +* Install -#+begin_src bash -guix package -i git -export GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt -#+end_src +The quickest way to install GN2 is by using a binary installation +(tarball or Docker image). These installations are bundled by GNU +Guix and include all dependencies. You can install GeneNetwork on most +Linux distributions, including Debian, Ubuntu, Fedora and CentOS, +provided you have administrator privileges (root). The alternative is +a Docker installation. -check out the git repositories (gn-deploy branch) +** Tarball -#+begin_src bash -cd ~ -mkdir genenetwork -cd genenetwork -git clone --branch gn-deploy https://github.com/genenetwork/guix-bioinformatics -git clone --branch gn-deploy --recursive https://github.com/genenetwork/guix guix-gn-deploy -cd guix-gn-deploy -#+end_src bash +Download the ~800Mb tarball from +[[http://files.genenetwork.org/software/binary_tarball/]]. Validate the checksum and +unpack to root, for example -To test whether this is working try: +: tar xvzf genenetwork2-2.10rc3-1538ffd-tarball-pack.tar.gz +: mv /gnu / +: mv /opt/genenetwork2 /opt/ -#+begin_src bash -#+end_src bash +Now you shoud be able to start the server with +: /opt/genenetwork2/bin/genenetwork2 -** Step 3: Authorize the GN Guix server +When the server stops with a MySQL error [[#run-mysql-server][Run MySQL server]] +and set SQL_URI to point at it. For example: -GN2 has its own GNU Guix binary distribution server. To trust it you have -to add the following key +: export SQL_URI=mysql://gn2:mysql_password@127.0.0.1/db_webqtl_s -#+begin_src scheme -(public-key - (ecc - (curve Ed25519) - (q #11217788B41ADC8D5B8E71BD87EF699C65312EC387752899FE9C888856F5C769#) - ) -) -#+end_src +See also [[#mysql-cant-connect-server-through-socket-error][Mysql can't connect server through socket ERROR]]. -by pasting it into the command +** Docker -#+begin_src bash -guix archive --authorize -#+end_src +Docker images are also available through +[[http://files.genenetwork.org/software/]]. Validate the checksum and run +with [[https://docs.docker.com/engine/reference/commandline/load/][Docker load]]. -and hit Ctrl-D. +** With source -Now you can use the substitute server to install GN2 binaries. +For more elaborate installation instructions on deploying GeneNetwork from +source see [[#source-deployment][Source deployment]]. -** Step 4: Install and run GN2 +* Running GN2 -Since this is a quick and dirty install we are going to override the -GNU Guix package path by pointing the package path to our repository: +Default settings for GN2 are listed in a file called +[[../etc/default_settings.py][default_settings.py]]. You can copy this file and pass it as a new +parameter to the genenetwork2 command, e.g. -#+begin_src bash -rm /root/.config/guix/latest -ln -s ~/genenetwork/guix-gn-deploy/ /root/.config/guix/latest -#+end_src +: genenetwork2 mysettings.py -Now check whether you can find the GN2 package with +or you can set environment variables to override individual parameters, e.g. -#+begin_src bash -env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ guix package -A genenetwork2 - genenetwork2 2.0-a8fcff4 out gn/packages/genenetwork.scm:144:2 -#+end_src - -(ignore the source file newer then ... messages, this is caused by the -/root/.config/guix/latest override). +: env SERVER_PORT=5004 SQL_URI=mysql://user:pwd@dbhostname/db_webqtl genenetwork2 -And install with +the debug and logging switches can be particularly useful when +developing GN2. -#+begin_src bash -env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ \ - guix package -i genenetwork2 \ - --substitute-urls="http://guix.genenetwork.org" -#+end_src - -Note: the order of the substitute url's may make a difference in speed -(put the one first that is fastest for your location and time of day). - -Note: if your system starts building or gives an error it may well be -Step 3 did not succeed. The installation should actually be smooth at -this point and only do binary installs (no compiling). - -After installation you should be able to run genenetwork2 after updating -the Guix suggested environment vars. Check the output of - -#+begin_src bash -guix package --search-paths -export PYTHONPATH="/root/.guix-profile/lib/python2.7/site-packages" -export R_LIBS_SITE="/root/.guix-profile/site-library/" -#+end_src +* Run MySQL server +** Install MySQL with GNU GUIx -and copy-paste the listed exports into the terminal before running: +These are the steps you can take to install a fresh installation of +mysql (which comes as part of the GNU Guix genenetwork2 install). -#+begin_src bash -genenetwork2 -#+end_src +As root configure and run -It will complain that the database is missing. See the next section on -running MySQL server for downloading and installing a MySQL GN2 -database. After installing the database restart genenetwork2 and point -your browser at [[http://localhost:5003/]]. +: adduser mysql && addgroup mysql +: mysqld --datadir=/var/mysql --initialize-insecure +: mkdir -p /var/run/mysqld +: chown mysql.mysql ~/mysql /var/run/mysqld +: su mysql -c mysqld --datadir=/var/mysql --explicit_defaults_for_timestamp -P 12048 -End of the GN2 installation recipe! +/etc/my.cnf +[mysqld] +user=root -* Run MySQL server +** Load the small database in MySQL At this point we require the underlying distribution to install and -run mysqld. Currently we have two databases for deployment, +run mysqld (see next section for GNU Guix). Currently we have two databases for deployment, 'db_webqtl_s' is the small testing database containing experiments from BXD mice and 'db_webqtl_plant' which contains all plant related material. Download one database from -http://files.genenetwork.org/raw_database/ -https://s3.amazonaws.com/genenetwork2/db_webqtl_s.zip +[[http://files.genenetwork.org/raw_database/]] + +[[https://s3.amazonaws.com/genenetwork2/db_webqtl_s.zip]] Check the md5sum. After installation inflate the database binary in the MySQL directory -(this installation path is subject to change soon) +: cd ~/mysql : chown -R mysql:mysql db_webqtl_s/ : chmod 700 db_webqtl_s/ : chmod 660 db_webqtl_s/* -restart MySQL service (mysqld). Login as root and +restart MySQL service (mysqld). Login as root + +: myslq -u root + +and : mysql> show databases; : +--------------------+ @@ -241,9 +153,12 @@ Set permissions and match password in your settings file below: : mysql> grant all privileges on db_webqtl_s.* to gn2@"localhost" identified by 'mysql_password'; +You may need to change "localhost" to whatever domain you are +connecting from (mysql will give an error). + Note that if the mysql connection is not working, try connecting to the IP address and check server firewall, hosts.allow and mysql IP -configuration. +configuration (see below). Note for the plant database you can rename it to db_webqtl_s, or change the settings in etc/default_settings.py to match your path. @@ -255,183 +170,9 @@ Graph of all runtime dependencies as installed by GNU Guix. #+ATTR_HTML: :title GN2_graph http://biogems.info/contrib/genenetwork/gn2.svg -* Source deployment - -This section gives a more elaborate instruction for installing GN2 -from source. - -First execute above 4 steps: - - - [[#step-1-install-gnu-guix][Step 1: Install GNU Guix]] - - [[#step-2-checkout-the-gn2-git-repositories][Step 2: Checkout the GN2 git repositories]] - - [[#step-3-authorize-the-gn-guix-server][Step 3: Authorize the GN Guix server]] - - [[#step-4-install-and-run-gn2-][Step 4: Install and run GN2 ]] - - -** Run your own copy of GN2 - -At some point you may want to fix the source code. Assuming you have -Guix and Genenetwork2 installed (as described above) clone the GN2 -repository from https://github.com/genenetwork/genenetwork2. - -Copy-paste the paths into your terminal (mainly so PYTHON_PATH and -R_LIBS_SITE are set) from the information given by guix: - -: guix package --search-paths - -Inside the repository: - -: cd genenetwork2 -: ./bin/genenetwork2 - -Will fire up your local repo http://localhost:5003/ using the -settings in ./etc/default_settings.py. These settings may -not reflect your system. To override settings create your own from a copy of -default_settings.py and pass it into GN2 with - -: ./bin/genenetwork2 $HOME/my_settings.py - -and everything *should* work (note the full path to the settings -file). This way we develop against the exact same dependency graph of -software. - -If something is not working, take a hint from the settings file -that comes in the Guix installation. It sits in something like +* Working with the GN2 source code -: cat ~/.guix-profile/lib/python2.7/site-packages/genenetwork2-2.0-py2.7.egg/etc/default_settings.py - -** Set up nginx port forwarding - -nginx can be used as a reverse proxy for GN2. For example, we want to -expose GN2 on port 80 while it is running on port 5003. Essentially -the configuration looks like - -#+begin_src js - server { - listen 80; - server_name test-gn2.genenetwork.org; - access_log logs/test-gn2.access.log; - - proxy_connect_timeout 3000; - proxy_send_timeout 3000; - proxy_read_timeout 3000; - send_timeout 3000; - - location / { - proxy_set_header Host $http_host; - proxy_set_header Connection keep-alive; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $server_name; - proxy_pass http://127.0.0.1:5003; - } -} -#+end_src js - -Install the nginx webserver (as root) - -: guix package -i nginx - -The nginx example configuration examples can be found in the Guix -store through - -: ls -l /root/.guix-profile/sbin/nginx -: lrwxrwxrwx 3 root guixbuild 66 Dec 31 1969 /root/.guix-profile/sbin/nginx -> /gnu/store/g0wrcl5z27rmk5b52rldzvk1bzzbnz2l-nginx-1.8.1/sbin/nginx - -Use that path - -: ls /gnu/store/g0wrcl5z27rmk5b52rldzvk1bzzbnz2l-nginx-1.8.1/share/nginx/conf/ -: fastcgi.conf koi-win scgi_params -: fastcgi.conf.default mime.types scgi_params.default -: fastcgi_params mime.types.default uwsgi_params -: fastcgi_params.default nginx.conf uwsgi_params.default -: koi-utf nginx.conf.default win-utf - -And copy any relevant files to /etc/nginx. A configuration file for -GeneNetwork (reverse proxy) port forwarding can be found in the source -repository under ./etc/nginx-genenetwork.conf. Copy this file to /etc -(still as root) -: cp ./etc/nginx-genenetwork.conf /etc/nginx/ - -Make dirs - -: mkdir -p /var/spool/nginx/logs - -Add users - -: adduser nobody ; addgroup nobody - -Run nginx - -: /root/.guix-profile/sbin/nginx -c /etc/nginx/nginx-genenetwork.conf -p /var/spool/nginx - -* Source deployment and other information on reproducibility - -See the document [[GUIX-Reproducible-from-source.org]]. - -** Update to recent guix - -We now compile Guix from scratch. - -Create, install and run a recent version of the guix-daemon by -compiling the guix repository you have installed with git in -step 2. Follow [[https://github.com/pjotrp/guix-notes/blob/master/INSTALL.org#building-gnu-guix-from-source-using-guix][these]] steps carefully after - -: cd ~/genenetwork/guix-gn-deploy - -Make sure to restart the guix daemon and run guix client from this -directory. - -** Install GN2 - -Reinstall genenetwork2 using the new tree - -#+begin_src bash -env GUIX_PACKAGE_PATH=~/genenetwork/guix-bioinformatics/ ./pre-inst-env guix package -i genenetwork2 --substitute-urls="http://guix.genenetwork.org https://mirror.guixsd.org" -#+end_src bash - -Note the use of ./pre-inst-env here! - -Actually, it should be the same installation as in step 4, so nothing -gets downloaded. - -** Run GN2 - -Make a note of the paths with - -#+begin_src bash -./pre-inst-env guix package --search-paths -#+end_src bash - -or this should also work if guix is installed - -#+begin_src bash -guix package --search-paths -#+end_src bash - -After setting the paths for the server - -#+begin_src bash -export PATH=~/.guix-profile/bin:$PATH -export PYTHONPATH="$HOME/.guix-profile/lib/python2.7/site-packages" -export R_LIBS_SITE="$HOME/.guix-profile/site-library/" -export GUIX_GTK3_PATH="$HOME/.guix-profile/lib/gtk-3.0" -export GI_TYPELIB_PATH="$HOME/.guix-profile/lib/girepository-1.0" -export XDG_DATA_DIRS="$HOME/.guix-profile/share" -export GIO_EXTRA_MODULES="$HOME/.guix-profile/lib/gio/modules" -#+end_src bash - -run the main script (in ~/.guix-profile/bin) - -#+begin_src bash -genenetwork2 -#+end_src bash - -will start the default server which listens on port 5003, i.e., -http://localhost:5003/. - -OK, we are where we were before with step 4. Only difference is that we -used our own compiled guix server. +See [[development.org]]. * Trouble shooting @@ -479,6 +220,31 @@ R_LIBS_SITE. Please check your GNU Guix GN2 installation paths, you man need to reinstall. Note that this may be the point you may want to start using profiles (see profile section). +** Mysql can't connect server through socket ERROR + +The following error + +: sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (2002, 'Can\'t connect to local MySQL server through socket \'/run/mysqld/mysqld.sock\' (2 "No such file or directory")') + +means that MySQL is trying to connect locally to a non-existent MySQL +server, something you may see in a container. Typically replicated with something like + +: mysql -h localhost + +try to connect over the network interface instead, e.g. + +: mysql -h 127.0.0.1 + +if that works run genenetwork after setting SQL_URI to something like + +: export SQL_URI=mysql://gn2:mysql_password@127.0.0.1/db_webqtl_s + +* Read more + +If you want to understand the architecture of GN2 read +[[Architecture.org]]. The rest of this document is mostly on deployment +of GN2. + * IRC session Here an IRC session where we installed GN2 from scratch using GNU Guix diff --git a/doc/development.org b/doc/development.org new file mode 100644 index 00000000..bbb6084f --- /dev/null +++ b/doc/development.org @@ -0,0 +1,23 @@ +* Development + +After cloning the git source tree you can run the contained GN2 using +an existing GN2_PROFILE, i.e., use a profile that was create to run a +binary installation of GN2. This profile may be found by typing + +: which genenetwork2 +: /home/wrk/opt/gn-latest-guix/bin/genenetwork2 + +An example of running the development version would be + +: env GN2_PROFILE=/home/wrk/opt/gn-latest-guix ./bin/genenetwork2 + +Profiles are stored in /gnu/store, so you may pick one up there + +: readlink -f $(dirname $(dirname `which genenetwork2`)) +: /gnu/store/dvckpaw770b00l6rv4ijql8wrk11iypv-profile + +and use that instead. + +Note that the genenetwork2 script sets up the environment for running +the webserver. This includes path to R modules and python modules. These +are output on startup. To make sure there is no environment pollution you can diff --git a/etc/VERSION b/etc/VERSION new file mode 100644 index 00000000..1785aa28 --- /dev/null +++ b/etc/VERSION @@ -0,0 +1 @@ +2.10rc3 diff --git a/etc/default_settings.py b/etc/default_settings.py index 6acea637..4f3a6f5c 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -9,6 +9,8 @@ # env LOG_SQL=True USE_REDIS=False ./bin/genenetwork2 # env LOG_LEVEL=DEBUG ./bin/genenetwork2 ~/gn2_settings.py # +# Typically you need to set GN2_PROFILE too. +# # Note also that in the near future we will additionally fetch # settings from a JSON file # @@ -18,10 +20,9 @@ import os import sys -GN_VERSION = open("../VERSION","r").read() +GN_VERSION = open("../etc/VERSION","r").read() SQL_URI = "mysql://gn2:mysql_password@localhost/db_webqtl_s" -SQLALCHEMY_DATABASE_URI = 'mysql://gn2:mysql_password@localhost/db_webqtl_s' -SQLALCHEMY_POOL_RECYCLE = 3600 +SQL_ALCHEMY_POOL_RECYCLE = 3600 GN_SERVER_URL = "http://localhost:8880/" # ---- Flask configuration (see website) @@ -45,24 +46,24 @@ WEBSERVER_DEPLOY = None # Deployment specifics (nyi) LOG_LEVEL = 'WARNING' # Logger mode (DEBUG|INFO|WARNING|ERROR|CRITICAL) LOG_LEVEL_DEBUG = '0' # logger.debugf log level (0-5, 5 = show all) LOG_SQL = 'False' # Log SQL/backend and GN_SERVER calls -LOG_SQLALCHEMY = 'False' +LOG_SQL_ALCHEMY = 'False' LOG_BENCH = True # Log bench marks USE_REDIS = True # REDIS caching (note that redis will be phased out) USE_GN_SERVER = 'False' # Use GN_SERVER SQL calls +HOME = os.environ['HOME'] -# Paths to JS libraries - -TWITTER_POST_FETCHER_JS_PATH = os.environ['HOME']+"/genenetwork/Twitter-Post-Fetcher" +# ---- Path overrides for Genenetwork - the defaults are normally +# picked up from Guix or in the HOME directory -# ---- Path overrides for Genenetwork # TMPDIR is normally picked up from the environment -HOME=os.environ['HOME'] -LOGFILE = HOME+"/genenetwork2.log" -GENENETWORK_FILES = HOME+"/gn2_data" # base dir for all static data files -LOCAL_PRIVATE_FILES = HOME+"/gn2_private_data" # private static data files +# GENENETWORK_FILES = HOME+"/gn2_data" # base dir for all static data files +# PRIVATE_FILES = HOME+"/gn2_private_data" # private static data files (unused) + +# ---- Local path to JS libraries - for development modules (only) +# GN2_JS_PATH = os.environ['HOME']+"/genenetwork/javascript" (unused) -# ---- GN2 Executables -PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read()) -PLINK_COMMAND = str.strip(os.popen("which plink2").read()) -GEMMA_COMMAND = str.strip(os.popen("which gemma").read()) +# ---- GN2 Executables (overwrite for testing only) +# PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read()) +# PLINK_COMMAND = str.strip(os.popen("which plink2").read()) +# GEMMA_COMMAND = str.strip(os.popen("which gemma").read()) diff --git a/test/lib/main_web_functionality.rb b/test/lib/main_web_functionality.rb index ec61de2d..9ae49995 100644 --- a/test/lib/main_web_functionality.rb +++ b/test/lib/main_web_functionality.rb @@ -13,16 +13,20 @@ describe MainWebFunctionality do it "Get to trait page" do page = @agent.get($host) + p page form = page.forms[1] form.buttons[0].value.must_equal "Search" # main menu is loaded # http://localhost:5003/search?species=mouse&group=BXD&type=Hippocampus+mRNA&dataset=HC_M2_0606_P&search_terms_or=&search_terms_and=MEAN%3D%2815+16%29+LRS%3D%2823+46%29&FormID=searchResult + form.fields[0].value.must_equal "searchResult" form.fields[2].value = "MEAN=(15 16) LRS=(23 46)" form.fields[3].value = "mouse" form.fields[4].value = "BXD" form.fields[5].value = "Hippocampus mRNA" form.fields[6].value = "HC_M2_0606_P" search_page = @agent.submit(form, form.buttons.first) + p "==================" + p search_page probe_link = search_page.links.find { |l| l.text =~ /1435395_s_at/ } probe_link.uri.to_s.must_equal "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P" show_trait_page = probe_link.click diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py index 1e47e183..e5f10edf 100644 --- a/wqflask/base/webqtlConfig.py +++ b/wqflask/base/webqtlConfig.py @@ -65,7 +65,7 @@ ENSEMBLETRANSCRIPT_URL="http://useast.ensembl.org/Mus_musculus/Lucene/Details?sp # want to reach this base dir assert_writable_dir(TEMPDIR) -TMPDIR = mk_dir(TEMPDIR+'gn2') +TMPDIR = mk_dir(TEMPDIR+'/gn2/') assert_writable_dir(TMPDIR) CACHEDIR = mk_dir(TMPDIR+'/cache/') diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index e5726656..a5fd86e2 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -57,7 +57,7 @@ import urlparse from pprint import pformat as pf -#Engine = sa.create_engine(zach_settings.SQLALCHEMY_DATABASE_URI) +#Engine = sa.create_engine(zach_settings.SQL_URI) # build MySql database connection diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index c28c617a..d46a84ba 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -205,21 +205,24 @@ SQL_URI = get_setting('SQL_URI') LOG_LEVEL = get_setting('LOG_LEVEL') LOG_LEVEL_DEBUG = get_setting_int('LOG_LEVEL_DEBUG') LOG_SQL = get_setting_bool('LOG_SQL') -LOG_SQLALCHEMY = get_setting_bool('LOG_SQLALCHEMY') +LOG_SQL_ALCHEMY = get_setting_bool('LOG_SQL_ALCHEMY') LOG_BENCH = get_setting_bool('LOG_BENCH') LOG_FORMAT = "%(message)s" # not yet in use USE_REDIS = get_setting_bool('USE_REDIS') USE_GN_SERVER = get_setting_bool('USE_GN_SERVER') GENENETWORK_FILES = get_setting('GENENETWORK_FILES') -TEMP_TRAITS = get_setting('TEMP_TRAITS') +GUIX_JS_PATH = get_setting('GUIX_JS_PATH') +assert_dir(GUIX_JS_PATH) PYLMM_COMMAND = pylmm_command() GEMMA_COMMAND = gemma_command() -GEMMA_RESULTS_PATH = get_setting('GEMMA_RESULTS_PATH') PLINK_COMMAND = plink_command() TEMPDIR = tempdir() # defaults to UNIX TMPDIR +TWITTER_POST_FETCHER_JS_PATH = GUIX_JS_PATH + "/Twitter-Post-Fetcher" +assert_dir(TWITTER_POST_FETCHER_JS_PATH) + from six import string_types if os.environ.get('WQFLASK_OVERRIDES'): @@ -234,5 +237,3 @@ if os.environ.get('WQFLASK_OVERRIDES'): else: OVERRIDES[k] = cmd logger.debug(OVERRIDES) - -assert_dir(get_setting("TWITTER_POST_FETCHER_JS_PATH")) diff --git a/wqflask/wqflask/database.py b/wqflask/wqflask/database.py index 4df872ad..96c2c301 100644 --- a/wqflask/wqflask/database.py +++ b/wqflask/wqflask/database.py @@ -22,8 +22,8 @@ def init_db(): # they will be registered properly on the metadata. Otherwise # you will have to import them first before calling init_db() #import yourapplication.models + logger.info("Initializing database connection") import wqflask.model - logger.debug("Creating all model metadata") Base.metadata.create_all(bind=engine) logger.info("Done creating all model metadata") diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index 87532445..8882c515 100644 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -37,7 +37,7 @@ from utility import temp_data from utility.benchmark import Bench from wqflask.marker_regression import gemma_mapping, rqtl_mapping, qtlreaper_mapping, plink_mapping -from utility.tools import locate, locate_ignore_error, PYLMM_COMMAND, GEMMA_COMMAND, GEMMA_RESULTS_PATH, PLINK_COMMAND, TEMPDIR +from utility.tools import locate, locate_ignore_error, PYLMM_COMMAND, GEMMA_COMMAND, PLINK_COMMAND, TEMPDIR from utility.external import shell from base.webqtlConfig import TMPDIR, GENERATED_TEXT_DIR diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index ec55ebeb..9ca3d63a 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -144,7 +144,7 @@

Development and source code on github with issue tracker and documentation. Join the mailing list and find us on IRC (#genenetwork channel). {% if version: %} -

GeneNetwork v{{ version }}

+

GeneNetwork {{ version }}

{% endif %}
diff --git a/wqflask/wqflask/templates/error.html b/wqflask/wqflask/templates/error.html index c707a4fc..2f1e06fa 100644 --- a/wqflask/wqflask/templates/error.html +++ b/wqflask/wqflask/templates/error.html @@ -35,7 +35,7 @@

-    GeneNetwork v{{ version }} {{ stack[0] }}
+    GeneNetwork {{ version }} {{ stack[0] }}
     {{ message }} (error)
     {{ stack[-3] }}
     {{ stack[-2] }}
@@ -50,7 +50,7 @@
   Toggle full stack trace
   
-      GeneNetwork v{{ version }} {% for line in stack %} {{ line }}
+      GeneNetwork {{ version }} {% for line in stack %} {{ line }}
       {% endfor %}
     
diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 1e831896..f7fcd2d0 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -46,7 +46,7 @@ from wqflask.database import db_session from wqflask import model from utility import Bunch, Struct, after -from utility.tools import LOG_SQL, LOG_SQLALCHEMY +from utility.tools import LOG_SQL, LOG_SQL_ALCHEMY import logging from utility.logger import getLogger @@ -69,7 +69,7 @@ class AnonUser(object): if self.cookie: logger.debug("already is cookie") self.anon_id = verify_cookie(self.cookie) - + else: logger.debug("creating new cookie") self.anon_id, self.cookie = create_signed_cookie() @@ -78,17 +78,17 @@ class AnonUser(object): @after.after_this_request def set_cookie(response): response.set_cookie(self.cookie_name, self.cookie) - + def add_collection(self, new_collection): collection_dict = dict(name = new_collection.name, created_timestamp = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p'), changed_timestamp = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p'), num_members = new_collection.num_members, members = new_collection.get_members()) - + Redis.set(self.key, json.dumps(collection_dict)) Redis.expire(self.key, 60 * 60 * 24 * 5) - + def delete_collection(self, collection_name): existing_collections = self.get_collections() updated_collections = [] @@ -106,7 +106,7 @@ class AnonUser(object): updated_collections.append(this_collection) Redis.set(self.key, json.dumps(updated_collections)) - + def get_collections(self): json_collections = Redis.get(self.key) if json_collections == None or json_collections == "None": @@ -117,7 +117,7 @@ class AnonUser(object): collection['created_timestamp'] = datetime.datetime.strptime(collection['created_timestamp'], '%b %d %Y %I:%M%p') collection['changed_timestamp'] = datetime.datetime.strptime(collection['changed_timestamp'], '%b %d %Y %I:%M%p') return collections - + def import_traits_to_user(self): collections_list = json.loads(Redis.get(self.key)) for collection in collections_list: @@ -131,7 +131,7 @@ class AnonUser(object): uc.members = json.dumps(collection['members']) db_session.add(uc) db_session.commit() - + def display_num_collections(self): """ Returns the number of collections or a blank string if there are zero. @@ -217,7 +217,7 @@ class UserSession(object): """Actual sqlalchemy record""" # Only look it up once if needed, then store it try: - if LOG_SQLALCHEMY: + if LOG_SQL_ALCHEMY: logging.getLogger('sqlalchemy.pool').setLevel(logging.DEBUG) # Already did this before @@ -237,7 +237,7 @@ class UserSession(object): def before_request(): g.user_session = UserSession() g.cookie_session = AnonUser() - + class UsersManager(object): def __init__(self): self.users = model.User.query.all() @@ -541,9 +541,9 @@ class LoginUser(object): import_col = "true" else: import_col = "false" - - #g.cookie_session.import_traits_to_user() - + + #g.cookie_session.import_traits_to_user() + return self.actual_login(user, import_collections=import_col) else: diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 39f4a686..3882e60a 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -53,7 +53,7 @@ from wqflask.ctl import ctl_analysis #from wqflask.trait_submission import submit_trait from utility import temp_data -from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION +from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION,TWITTER_POST_FETCHER_JS_PATH from utility.helper_functions import get_species_groups from base import webqtlFormData @@ -148,8 +148,7 @@ def tmp_page(img_path): @app.route("/twitter/") def bd_files(filename): - bd_path = app.config['TWITTER_POST_FETCHER_JS_PATH'] - return send_from_directory(bd_path, filename) + return send_from_directory(TWITTER_POST_FETCHER_JS_PATH, filename) #@app.route("/data_sharing") #def data_sharing_page(): -- cgit v1.2.3 From e6afa39ac0bf769bed181ad9e16fc4fc8e16bb22 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 22 May 2017 15:48:25 +0000 Subject: Added print lines showing url to views.py and updated dataset menu json file --- .../new/javascript/dataset_menu_structure.json | 284 +++++++++++++++++---- wqflask/wqflask/views.py | 34 ++- 2 files changed, 264 insertions(+), 54 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json index 861af3d6..f3712b5d 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json +++ b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json @@ -1339,15 +1339,15 @@ "HLC_0311", "GSE9588 Human Liver Normal (Mar11) Both Sexes" ], - [ - "384", - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ], [ "383", "HLCM_0311", "GSE9588 Human Liver Normal (Mar11) Males" + ], + [ + "384", + "HLCF_0311", + "GSE9588 Human Liver Normal (Mar11) Females" ] ], "Phenotypes": [ @@ -1493,6 +1493,15 @@ ] ] }, + "Islets-Gerling": { + "Phenotypes": [ + [ + "None", + "Islets-GerlingPublish", + "Islets-Gerling Published Phenotypes" + ] + ] + }, "TIGEM-Retina-RNA-Seq": { "Phenotypes": [ [ @@ -1560,6 +1569,11 @@ ] ], "Heart mRNA": [ + [ + "820", + "UCLA_AXB_BXA_Aor_Jan16", + "UCLA AXB/BXA Aorta Affy M430 2.0 (Jan16) RMA" + ], [ "421", "IRCM_AXBXA_HRI0213", @@ -1567,6 +1581,11 @@ ] ], "Liver mRNA": [ + [ + "822", + "UCLA_AXB_BXA_Liv_Jan16", + "UCLA AXB/BXA Liver Affy M430 2.0 (Jan16) RMA" + ], [ "352", "GSE16780AB_UCLA_ML0911", @@ -1726,11 +1745,6 @@ ] ], "Striatum mRNA": [ - [ - "85", - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ], [ "84", "SA_M2_0905_R", @@ -1740,21 +1754,26 @@ "83", "SA_M2_0905_M", "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" + ], + [ + "85", + "SA_M2_0905_P", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" ] ] }, "BHF2": { "Adipose mRNA": [ - [ - "197", - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], [ "196", "UCLA_BHF2_ADIPOSE_MALE", "UCLA BHF2 Adipose Male mlratio" ], + [ + "197", + "UCLA_BHF2_ADIPOSE_FEMALE", + "UCLA BHF2 Adipose Female mlratio" + ], [ "165", "UCLA_BHF2_ADIPOSE_0605", @@ -1762,16 +1781,16 @@ ] ], "Brain mRNA": [ - [ - "199", - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], [ "198", "UCLA_BHF2_BRAIN_MALE", "UCLA BHF2 Brain Male mlratio" ], + [ + "199", + "UCLA_BHF2_BRAIN_FEMALE", + "UCLA BHF2 Brain Female mlratio" + ], [ "166", "UCLA_BHF2_BRAIN_0605", @@ -1786,16 +1805,16 @@ ] ], "Liver mRNA": [ - [ - "201", - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], [ "200", "UCLA_BHF2_LIVER_MALE", "UCLA BHF2 Liver Male mlratio" ], + [ + "201", + "UCLA_BHF2_LIVER_FEMALE", + "UCLA BHF2 Liver Female mlratio" + ], [ "167", "UCLA_BHF2_LIVER_0605", @@ -1999,11 +2018,6 @@ "BR_U_1105_P", "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" ], - [ - "81", - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], [ "80", "BR_U_0805_M", @@ -2014,6 +2028,11 @@ "BR_U_0805_R", "UTHSC Brain mRNA U74Av2 (Aug05) RMA" ], + [ + "81", + "BR_U_0805_P", + "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" + ], [ "42", "CB_M_0204_P", @@ -2142,6 +2161,13 @@ "BXD Genotypes" ] ], + "Heart mRNA": [ + [ + "819", + "UCLA_BXD_Aor_Jan16", + "UCLA BXD Aorta Affy M430 2.0 (Jan16) RMA" + ] + ], "Hematopoietic Cells mRNA": [ [ "149", @@ -2217,6 +2243,26 @@ "UMUTAffyExon_0209_RMA", "UMUTAffy Hippocampus Exon (Feb09) RMA" ], + [ + "814", + "UTHSC_ILM_BXD_hipp_NOSb_0217", + "UTHSC BXD Hippocampus ILM v6.1 NOS Balanced (Feb17) RankInv" + ], + [ + "815", + "UTHSC_ILM_BXD_hipp_NOEb_0217", + "UTHSC BXD Hippocampus ILM v6.1 NOE Balanced (Feb17) RankInv" + ], + [ + "816", + "UTHSC_ILM_BXD_hipp_RSSb_0217", + "UTHSC BXD Hippocampus ILM v6.1 RSS Balanced (Feb17) RankInv" + ], + [ + "817", + "UTHSC_ILM_BXD_hipp_RSEb_0217", + "UTHSC BXD Hippocampus ILM v6.1 RSE Balanced (Feb17) RankInv" + ], [ "780", "UTHSC_ILM_BXD_hipp_NOEb_0216", @@ -2390,15 +2436,25 @@ ] ], "Liver Proteome": [ + [ + "540", + "EPFLETHZBXDprotCD0514", + "EPFL/ETHZ BXD Liver, Chow Diet (Jun16) Top100 SWATH" + ], + [ + "541", + "EPFLETHZBXDprotHFD0514", + "EPFL/ETHZ BXD Liver, High Fat Diet (Jun16) Top100 SWATH" + ], [ "704", "EPFLETHZBXDprotCD_LS1114", - "EPFL/ETHZ BXD Liver, Chow Diet (Oct14) Light SWATH" + "EPFL/ETHZ BXD Liver, Chow Diet (Oct14) Top10 SWATH" ], [ "705", "EPFLETHZBXDprotHF_LS1114", - "EPFL/ETHZ BXD Liver, High Fat Diet (Oct14) Light SWATH" + "EPFL/ETHZ BXD Liver, High Fat Diet Diet (Oct14) Top10 SWATH" ], [ "703", @@ -2414,19 +2470,14 @@ "489", "EPFLBXDprotHFDRPN0214", "EPFL/LISP BXD Liver, Soluble Proteins HFD (Feb14) SRM" - ], - [ - "540", - "EPFLETHZBXDprotCD0514", - "EPFL/ETHZ BXD Liver, Soluble Proteins CD (Jun14) SWATH" - ], - [ - "541", - "EPFLETHZBXDprotHFD0514", - "EPFL/ETHZ BXD Liver, Soluble Proteins HFD (Jun14) SWATH" ] ], "Liver mRNA": [ + [ + "818", + "UCLA_BXD_Liv_Jan16", + "UCLA BXD Liver Affy M430 2.0 (Jan16) RMA" + ], [ "430", "EPFLMouseLiverRMA0413", @@ -2442,6 +2493,11 @@ "EPFLMouseLiverCDRMA0413", "EPFL/LISP BXD CD Liver Affy Mouse Gene 1.0 ST (Apr13) RMA" ], + [ + "433", + "EPFLMouseLiverBothExRMA0413", + "EPFL/LISP BXD CD+HFD Liver Affy Mouse Gene 1.0 ST (Apr13) RMA Exon Level" + ], [ "700", "UTHSC-VGX_MmBXDHepatocytesRMA1014", @@ -2466,6 +2522,51 @@ "702", "SUH_Liv_RMAEx_0611", "SUH BXD Liver CCl4-treated Affy Mouse Gene 1.0 ST Exon Level (Jun11) RMA" + ], + [ + "256", + "GenEx_BXD_liverEt_M5_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Both Sexes" + ], + [ + "257", + "GenEx_BXD_liverEt_M5M_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Males" + ], + [ + "258", + "GenEx_BXD_liverEt_M5F_0912", + "GenEx BXD EtOH Liver Affy M430 2.0 (Sep12) MAS5 Females" + ], + [ + "307", + "GenEx_BXD_liverEt_RMA_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes" + ], + [ + "308", + "GenEx_BXD_liverEt_RMA_M_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males" + ], + [ + "309", + "GenEx_BXD_liverEt_RMA_F_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females" + ], + [ + "310", + "GenEx_BXD_liverSal_RMA_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes" + ], + [ + "311", + "GenEx_BXD_liverSal_RMA_M_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males" + ], + [ + "312", + "GenEx_BXD_liverSal_RMA_F_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females" ] ], "Lung mRNA": [ @@ -2545,15 +2646,15 @@ "HQFNeoc_0208_RankInv", "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" ], - [ - "275", - "DevNeocortex_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv" - ], [ "274", "DevNeocortex_ILM6.2P3RInv_1110", "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv" + ], + [ + "275", + "DevNeocortex_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv" ] ], "Nucleus Accumbens mRNA": [ @@ -2760,11 +2861,6 @@ ] ], "Ventral Tegmental Area mRNA": [ - [ - "230", - "VCUEtvsSal_0609_R", - "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) RMA" - ], [ "229", "VCUEtOH_0609_R", @@ -2774,6 +2870,11 @@ "228", "VCUSal_0609_R", "VCU BXD VTA Sal M430 2.0 (Jun09) RMA" + ], + [ + "230", + "VCUEtvsSal_0609_R", + "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) RMA" ] ] }, @@ -2920,6 +3021,27 @@ ] ] }, + "CIE-RMA": { + "Midbrain mRNA": [ + [ + "830", + "INIA_UTHSC_Mid_AffyMTA1_Apr17", + "INIA-UTHSC Midbrain CIE Affy MTA 1.0 GeneLevel (Apr17) RMA" + ], + [ + "834", + "INIA_UTHSC_Mid_AffyMTA1_Ex_May17", + "INIA-UTHSC Midbrain CIE Affy MTA 1.0 Exon Level (Apr17) RMA" + ] + ], + "Phenotypes": [ + [ + "None", + "CIE-RMAPublish", + "CIE-RMA Published Phenotypes" + ] + ] + }, "CMS": { "Phenotypes": [ [ @@ -3021,6 +3143,13 @@ "CXB Genotypes" ] ], + "Heart mRNA": [ + [ + "821", + "UCLA_CXB_Aor_Jan16", + "UCLA CXB Aorta Affy M430 2.0 (Jan16) RMA" + ] + ], "Hippocampus mRNA": [ [ "100", @@ -3033,6 +3162,13 @@ "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" ] ], + "Liver mRNA": [ + [ + "823", + "UCLA_CXB_Liv_Jan16", + "UCLA CXB Liver Affy M430 2.0 (Jan16) RMA" + ] + ], "Phenotypes": [ [ "628", @@ -3048,6 +3184,7 @@ ] ] }, + "EMSR": {}, "HS": { "Hippocampus mRNA": [ [ @@ -3544,6 +3681,10 @@ "HSB", "Brain, Development: Normal Gene Expression (Yale/Sestan)" ], + [ + "Islets-Gerling", + "Pancreatic: Islets (UTHSC/Gerling)" + ], [ "TIGEM-Retina-RNA-Seq", "Retina: Normal Adult Gene Expression, RNA-Seq (TIGEM)" @@ -3616,7 +3757,11 @@ ], [ "CIE-INIA", - "Chronic Intermittent Ethanol" + "Chronic Intermittent Ethanol Phase 1" + ], + [ + "CIE-RMA", + "Chronic Intermittent Ethanol Phase 2" ], [ "CMS", @@ -3630,6 +3775,10 @@ "CXB", "CXB" ], + [ + "EMSR", + "Ethanol-Medicated Stress Reduction" + ], [ "HS", "Heterogeneous Stock" @@ -4414,6 +4563,12 @@ "Ventrolateral Prefrontal Cortex mRNA" ] ], + "Islets-Gerling": [ + [ + "Phenotypes", + "Phenotypes" + ] + ], "TIGEM-Retina-RNA-Seq": [ [ "Phenotypes", @@ -4629,6 +4784,10 @@ "Gastrointestinal mRNA", "Gastrointestinal mRNA" ], + [ + "Heart mRNA", + "Heart mRNA" + ], [ "Hematopoietic Cells mRNA", "Hematopoietic Cells mRNA" @@ -4780,6 +4939,16 @@ "LCM Brain Regions mRNA" ] ], + "CIE-RMA": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Midbrain mRNA", + "Midbrain mRNA" + ] + ], "CMS": [ [ "Phenotypes", @@ -4821,15 +4990,24 @@ "Genotypes", "Genotypes" ], + [ + "Heart mRNA", + "Heart mRNA" + ], [ "Hippocampus mRNA", "Hippocampus mRNA" ], + [ + "Liver mRNA", + "Liver mRNA" + ], [ "Spleen mRNA", "Spleen mRNA" ] ], + "EMSR": [], "HS": [ [ "Phenotypes", diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 39f4a686..24a7cbca 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -71,6 +71,8 @@ import werkzeug import utility.logger logger = utility.logger.getLogger(__name__ ) + + @app.before_request def connect_db(): db = getattr(g, '_database', None) @@ -120,6 +122,7 @@ def handle_bad_request(e): @app.route("/") def index_page(): logger.info("Sending index_page") + logger.error(request.url) params = request.args if 'import_collections' in params: import_collections = params['import_collections'] @@ -137,6 +140,7 @@ def index_page(): def tmp_page(img_path): logger.info("In tmp_page") logger.info("img_path:", img_path) + logger.error(request.url) initial_start_vars = request.form logger.info("initial_start_vars:", initial_start_vars) imgfile = open(GENERATED_IMAGE_DIR + img_path, 'rb') @@ -170,6 +174,7 @@ def bd_files(filename): @app.route("/search", methods=('GET',)) def search_page(): logger.info("in search_page") + logger.error(request.url) if 'info_database' in request.args: logger.info("Going to sharing_info_page") template_vars = sharing_info_page() @@ -208,6 +213,7 @@ def search_page(): @app.route("/gsearch", methods=('GET',)) def gsearchact(): + logger.error(request.url) result = gsearch.GSearch(request.args).__dict__ type = request.args['type'] if type == "gene": @@ -218,6 +224,7 @@ def gsearchact(): @app.route("/gsearch_updating", methods=('POST',)) def gsearch_updating(): logger.info("REQUEST ARGS:", request.values) + logger.error(request.url) result = update_search_results.GSearch(request.args).__dict__ return result['results'] # type = request.args['type'] @@ -228,26 +235,31 @@ def gsearch_updating(): @app.route("/docedit") def docedit(): + logger.error(request.url) doc = docs.Docs(request.args['entry']) return render_template("docedit.html", **doc.__dict__) @app.route('/generated/') def generated_file(filename): + logger.error(request.url) return send_from_directory(GENERATED_IMAGE_DIR,filename) @app.route("/help") def help(): + logger.error(request.url) doc = docs.Docs("help") return render_template("docs.html", **doc.__dict__) @app.route("/wgcna_setup", methods=('POST',)) def wcgna_setup(): logger.info("In wgcna, request.form is:", request.form) # We are going to get additional user input for the analysis + logger.error(request.url) return render_template("wgcna_setup.html", **request.form) # Display them using the template @app.route("/wgcna_results", methods=('POST',)) def wcgna_results(): logger.info("In wgcna, request.form is:", request.form) + logger.error(request.url) wgcna = wgcna_analysis.WGCNA() # Start R, load the package and pointers and create the analysis wgcnaA = wgcna.run_analysis(request.form) # Start the analysis, a wgcnaA object should be a separate long running thread result = wgcna.process_results(wgcnaA) # After the analysis is finished store the result @@ -256,11 +268,13 @@ def wcgna_results(): @app.route("/ctl_setup", methods=('POST',)) def ctl_setup(): logger.info("In ctl, request.form is:", request.form) # We are going to get additional user input for the analysis + logger.error(request.url) return render_template("ctl_setup.html", **request.form) # Display them using the template @app.route("/ctl_results", methods=('POST',)) def ctl_results(): logger.info("In ctl, request.form is:", request.form) + logger.error(request.url) ctl = ctl_analysis.CTL() # Start R, load the package and pointers and create the analysis ctlA = ctl.run_analysis(request.form) # Start the analysis, a ctlA object should be a separate long running thread result = ctl.process_results(ctlA) # After the analysis is finished store the result @@ -298,11 +312,13 @@ def environments(): @app.route("/submit_trait") def submit_trait_form(): + logger.error(request.url) species_and_groups = get_species_groups() return render_template("submit_trait.html", **{'species_and_groups' : species_and_groups, 'gn_server_url' : GN_SERVER_URL, 'version' : GN_VERSION}) @app.route("/create_temp_trait", methods=('POST',)) def create_temp_trait(): + logger.error(request.url) print("REQUEST.FORM:", request.form) #template_vars = submit_trait.SubmitTrait(request.form) @@ -315,6 +331,7 @@ def export_trait_excel(): """Excel file consisting of the sample data from the trait data and analysis page""" logger.info("In export_trait_excel") logger.info("request.form:", request.form) + logger.error(request.url) sample_data = export_trait_data.export_sample_table(request.form) logger.info("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) @@ -340,6 +357,7 @@ def export_trait_csv(): """CSV file consisting of the sample data from the trait data and analysis page""" logger.info("In export_trait_csv") logger.info("request.form:", request.form) + logger.error(request.url) sample_data = export_trait_data.export_sample_table(request.form) logger.info("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) @@ -360,6 +378,7 @@ def export_traits_csv(): """CSV file consisting of the traits from the search result page""" logger.info("In export_traits_csv") logger.info("request.form:", request.form) + logger.error(request.url) csv_data = export_traits.export_search_results_csv(request.form) return Response(csv_data, @@ -369,6 +388,7 @@ def export_traits_csv(): @app.route('/export_perm_data', methods=('POST',)) def export_perm_data(): """CSV file consisting of the permutation data for the mapping results""" + logger.error(request.url) num_perm = float(request.form['num_perm']) perm_data = json.loads(request.form['perm_results']) @@ -391,6 +411,7 @@ def export_perm_data(): @app.route("/show_temp_trait", methods=('POST',)) def show_temp_trait_page(): + logger.error(request.url) template_vars = show_trait.ShowTrait(request.form) #logger.info("js_data before dump:", template_vars.js_data) template_vars.js_data = json.dumps(template_vars.js_data, @@ -405,6 +426,7 @@ def show_temp_trait_page(): @app.route("/show_trait") def show_trait_page(): + logger.error(request.url) template_vars = show_trait.ShowTrait(request.args) #logger.info("js_data before dump:", template_vars.js_data) template_vars.js_data = json.dumps(template_vars.js_data, @@ -420,6 +442,7 @@ def show_trait_page(): @app.route("/heatmap", methods=('POST',)) def heatmap_page(): logger.info("In heatmap, request.form is:", pf(request.form)) + logger.error(request.url) start_vars = request.form temp_uuid = uuid.uuid4() @@ -469,6 +492,7 @@ def mapping_results_container_page(): @app.route("/loading", methods=('POST',)) def loading_page(): + logger.error(request.url) initial_start_vars = request.form logger.debug("Marker regression called with initial_start_vars:", initial_start_vars.items()) #temp_uuid = initial_start_vars['temp_uuid'] @@ -525,6 +549,7 @@ def loading_page(): def marker_regression_page(): initial_start_vars = request.form logger.debug("Marker regression called with initial_start_vars:", initial_start_vars.items()) + logger.error(request.url) temp_uuid = initial_start_vars['temp_uuid'] wanted = ( 'trait_id', @@ -646,6 +671,7 @@ def marker_regression_page(): @app.route("/export", methods = ('POST',)) def export(): logger.info("request.form:", request.form) + logger.error(request.url) svg_xml = request.form.get("data", "Invalid data") filename = request.form.get("filename", "manhattan_plot_snp") response = Response(svg_xml, mimetype="image/svg+xml") @@ -656,6 +682,7 @@ def export(): def export_pdf(): import cairosvg logger.info("request.form:", request.form) + logger.error(request.url) svg_xml = request.form.get("data", "Invalid data") logger.info("svg_xml:", svg_xml) filename = request.form.get("filename", "interval_map_pdf") @@ -668,7 +695,7 @@ def export_pdf(): @app.route("/network_graph", methods=('POST',)) def network_graph_page(): logger.info("In network_graph, request.form is:", pf(request.form)) - + logger.error(request.url) start_vars = request.form traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] if traits[0] != "": @@ -684,6 +711,7 @@ def network_graph_page(): @app.route("/corr_compute", methods=('POST',)) def corr_compute_page(): logger.info("In corr_compute, request.form is:", pf(request.form)) + logger.error(request.url) #fd = webqtlFormData.webqtlFormData(request.form) template_vars = show_corr_results.CorrelationResults(request.form) return render_template("correlation_page.html", **template_vars.__dict__) @@ -691,6 +719,7 @@ def corr_compute_page(): @app.route("/corr_matrix", methods=('POST',)) def corr_matrix_page(): logger.info("In corr_matrix, request.form is:", pf(request.form)) + logger.error(request.url) start_vars = request.form traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] @@ -706,6 +735,7 @@ def corr_matrix_page(): @app.route("/corr_scatter_plot") def corr_scatter_plot_page(): + logger.error(request.url) template_vars = corr_scatter_plot.CorrScatterPlot(request.args) template_vars.js_data = json.dumps(template_vars.js_data, default=json_default_handler, @@ -717,6 +747,7 @@ def corr_scatter_plot_page(): def sharing_info_page(): """Info page displayed when the user clicks the "Info" button next to the dataset selection""" logger.info("In sharing_info_page") + logger.error(request.url) fd = webqtlFormData.webqtlFormData(request.args) template_vars = SharingInfoPage.SharingInfoPage(fd) return template_vars @@ -724,6 +755,7 @@ def sharing_info_page(): # Take this out or secure it before putting into production @app.route("/get_temp_data") def get_temp_data(): + logger.error(request.url) temp_uuid = request.args['key'] return flask.jsonify(temp_data.TempData(temp_uuid).get_all()) -- cgit v1.2.3 From 1517b200476380179e5c53c141a874348e28dd87 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 22 May 2017 15:57:26 +0000 Subject: Added submit trait to header menu and fixed some minor issues with Network Graph interface --- wqflask/wqflask/templates/base.html | 3 +++ wqflask/wqflask/templates/network_graph.html | 17 ++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index ec55ebeb..ba8ef769 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -39,6 +39,9 @@
  • Search
  • +
  • + Submit Trait +
  • Collections {% if g.user_session.user_ob %} diff --git a/wqflask/wqflask/templates/network_graph.html b/wqflask/wqflask/templates/network_graph.html index 57426af7..50c0c230 100644 --- a/wqflask/wqflask/templates/network_graph.html +++ b/wqflask/wqflask/templates/network_graph.html @@ -45,7 +45,8 @@
  • @@ -82,20 +83,6 @@ - - - - - -
    Description Location MeanMax LRS ?Max LRS Max LRS LocationAdditive Effect ?Additive Effect
    {{ loop.index }} {% if g.user_session.user_ob %} {{ uc.name }}
    0               -               +/- 1 +               +              +/- 1
    - - - -
    - - - -
    -- cgit v1.2.3 From 755b9aaa31c73cc5fe8c1a75d74846f1d8594419 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Wed, 31 May 2017 07:12:28 +0000 Subject: JS module handling --- VERSION | 2 +- bin/genenetwork2 | 2 +- doc/development.org | 20 ++++++++++++++++++++ etc/default_settings.py | 2 +- wqflask/utility/tools.py | 37 +++++++++++++++++++++++++++++-------- wqflask/wqflask/views.py | 6 +++--- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/VERSION b/VERSION index 144b089a..3e0b7cab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.10-pre1 +2.10-pre4 diff --git a/bin/genenetwork2 b/bin/genenetwork2 index df688989..b3190f1e 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -68,7 +68,7 @@ else export PATH=$GN2_PROFILE/bin:$PATH export PYTHONPATH=$GN2_PROFILE/lib/python2.7/site-packages export R_LIBS_SITE=$GN2_PROFILE/site-library - export GUIX_JS_PATH=$GN2_PROFILE/share/genenetwork2/javascript + export JS_GUIX_PATH=$GN2_PROFILE/share/genenetwork2/javascript export GUIX_GTK3_PATH="$GN2_PROFILE/lib/gtk-3.0" export GI_TYPELIB_PATH="$GN2_PROFILE/lib/girepository-1.0" export XDG_DATA_DIRS="$GN2_PROFILE/share" diff --git a/doc/development.org b/doc/development.org index bbb6084f..5e6e318b 100644 --- a/doc/development.org +++ b/doc/development.org @@ -1,5 +1,7 @@ * Development +** Using GN2_PROFILE + After cloning the git source tree you can run the contained GN2 using an existing GN2_PROFILE, i.e., use a profile that was create to run a binary installation of GN2. This profile may be found by typing @@ -21,3 +23,21 @@ and use that instead. Note that the genenetwork2 script sets up the environment for running the webserver. This includes path to R modules and python modules. These are output on startup. To make sure there is no environment pollution you can + +** Javascript modules + +As of release 2.10-pre4 we Javascript modules are installed in three places: + +1. JS_GUIX_PATH: the Guix store - these are Guix pre-packaged modules +2. The git source tree (./wqflask/wqflask/static/packages/) +3. JS_GN_PATH: a local directory containing (temporary) development modules + +Packages currently in git (2) will move to JS_GUIX_PATH (1) over +time. This is to keep better track of origin updates. Putting packages +in git (2) is actively discouraged(!), unless there are GN2 specific +adaptations to the original Javascript modules. + +JS_GN_PATH (3) is for development purposes. By default is is set to +$HOME/genenetwork/javascript. Say you are working on an updated +version of a JS module not yet in (1) you can simply check out that +module in that path and it should show up. diff --git a/etc/default_settings.py b/etc/default_settings.py index 4f3a6f5c..1c5b10b4 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -61,7 +61,7 @@ HOME = os.environ['HOME'] # PRIVATE_FILES = HOME+"/gn2_private_data" # private static data files (unused) # ---- Local path to JS libraries - for development modules (only) -# GN2_JS_PATH = os.environ['HOME']+"/genenetwork/javascript" (unused) +JS_GN_PATH = os.environ['HOME']+"/genenetwork/javascript" # ---- GN2 Executables (overwrite for testing only) # PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read()) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index d46a84ba..c1c6fd36 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -13,6 +13,11 @@ logger = logging.getLogger(__name__ ) OVERRIDES = {} +def app_set(command_id, value): + """Set application wide value""" + app.config.setdefault(command_id,value) + value + def get_setting(command_id,guess=None): """Resolve a setting from the environment or the global settings in app.config, with valid_path is a function checking whether the @@ -40,6 +45,7 @@ def get_setting(command_id,guess=None): def value(command): if command: # sys.stderr.write("Found "+command+"\n") + app_set(command_id,command) return command else: return None @@ -89,6 +95,18 @@ def valid_path(dir): return dir return None +def js_path(module=None): + """ + Find the JS module in the two paths + """ + try_gn = get_setting("JS_GN_PATH")+"/"+module + if valid_path(try_gn): + return try_gn + try_guix = get_setting("JS_GUIX_PATH")+"/"+module + if valid_path(try_guix): + return try_guix + raise "No JS path found for "+module+" (check JS_GN_PATH)" + def pylmm_command(guess=None): return valid_bin(get_setting("PYLMM_COMMAND",guess)) @@ -212,16 +230,19 @@ USE_REDIS = get_setting_bool('USE_REDIS') USE_GN_SERVER = get_setting_bool('USE_GN_SERVER') GENENETWORK_FILES = get_setting('GENENETWORK_FILES') -GUIX_JS_PATH = get_setting('GUIX_JS_PATH') -assert_dir(GUIX_JS_PATH) - -PYLMM_COMMAND = pylmm_command() -GEMMA_COMMAND = gemma_command() -PLINK_COMMAND = plink_command() +JS_GUIX_PATH = get_setting('JS_GUIX_PATH') +assert_dir(JS_GUIX_PATH) +JS_GN_PATH = get_setting('JS_GN_PATH') +assert_dir(JS_GN_PATH) + +PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) +GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) +PLINK_COMMAND = app_set("PLINK_COMMAND",plink_command()) TEMPDIR = tempdir() # defaults to UNIX TMPDIR -TWITTER_POST_FETCHER_JS_PATH = GUIX_JS_PATH + "/Twitter-Post-Fetcher" -assert_dir(TWITTER_POST_FETCHER_JS_PATH) +# ---- Handle specific JS modules +JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("Twitter-Post-Fetcher")) +assert_dir(JS_TWITTER_POST_FETCHER_PATH) from six import string_types diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3882e60a..07151425 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -53,7 +53,7 @@ from wqflask.ctl import ctl_analysis #from wqflask.trait_submission import submit_trait from utility import temp_data -from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION,TWITTER_POST_FETCHER_JS_PATH +from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION,JS_TWITTER_POST_FETCHER_PATH from utility.helper_functions import get_species_groups from base import webqtlFormData @@ -147,8 +147,8 @@ def tmp_page(img_path): img_base64 = bytesarray ) @app.route("/twitter/") -def bd_files(filename): - return send_from_directory(TWITTER_POST_FETCHER_JS_PATH, filename) +def twitter(filename): + return send_from_directory(JS_TWITTER_POST_FETCHER_PATH, filename) #@app.route("/data_sharing") #def data_sharing_page(): -- cgit v1.2.3 From 41da1283c829e587a37e21c52f71f9b1c57be80b Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Wed, 31 May 2017 07:42:13 +0000 Subject: JS_GUIX_PATH may not be there --- wqflask/utility/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index c1c6fd36..49e3471e 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -231,7 +231,7 @@ USE_GN_SERVER = get_setting_bool('USE_GN_SERVER') GENENETWORK_FILES = get_setting('GENENETWORK_FILES') JS_GUIX_PATH = get_setting('JS_GUIX_PATH') -assert_dir(JS_GUIX_PATH) +# assert_dir(JS_GUIX_PATH) - don't enforce right now JS_GN_PATH = get_setting('JS_GN_PATH') assert_dir(JS_GN_PATH) -- cgit v1.2.3 From 6c3edf38ecc6549bc2cdf3893067d64a0a8e0ba3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 31 May 2017 16:01:21 +0000 Subject: Added various tool options to correlation results page and improved table appearance for mRNA assay data sets (still need to improve it for others) Fixed minor logic issue in trait.py --- wqflask/base/trait.py | 2 + wqflask/wqflask/templates/correlation_page.html | 152 +++++++++++++++++++++--- 2 files changed, 137 insertions(+), 17 deletions(-) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index e22a51e4..33a4efe9 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -206,6 +206,8 @@ class GeneralTrait(object): formatted = self.description if self.probe_target_description: formatted += "; " + self.probe_target_description + else: + formatted = "Not available" elif self.dataset.type == 'Publish': if self.confidential: formatted = self.pre_publication_description diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index f5fe2120..fbf373f6 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -21,6 +21,35 @@ and analysis page.

    +
    +
    + {% if uc %} + + {% endif %} + + + + + + + + + + + +
    +
    +

    @@ -31,9 +60,10 @@

    +
    - +
    @@ -99,7 +129,7 @@ {% for trait in correlation_results %} - + + @@ -167,8 +197,6 @@ - - -- cgit v1.2.3 From 4df8db0d30ea19f5cfc7ec7d4222a3590b217e5c Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 2 Jun 2017 10:14:30 +0000 Subject: settings: do not enforce JS paths --- wqflask/utility/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 49e3471e..393ff2df 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -233,7 +233,7 @@ GENENETWORK_FILES = get_setting('GENENETWORK_FILES') JS_GUIX_PATH = get_setting('JS_GUIX_PATH') # assert_dir(JS_GUIX_PATH) - don't enforce right now JS_GN_PATH = get_setting('JS_GN_PATH') -assert_dir(JS_GN_PATH) +# assert_dir(JS_GN_PATH) PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) -- cgit v1.2.3 From e467c3f19824415d9e9a3fdd4073d44439c83cbf Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 2 Jun 2017 10:21:05 +0000 Subject: settings: GENENETWORK_FILES --- bin/genenetwork2 | 2 +- etc/default_settings.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/genenetwork2 b/bin/genenetwork2 index b3190f1e..236d8f63 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -74,7 +74,7 @@ else export XDG_DATA_DIRS="$GN2_PROFILE/share" export GIO_EXTRA_MODULES="$GN2_PROFILE/lib/gio/modules" export LC_ALL=C # FIXME - export GENENETWORK_FILES="$GN2_PROFILE/share/genenetwork2" + export GUIX_GENENETWORK_FILES="$GN2_PROFILE/share/genenetwork2" export PLINK_COMMAND="$GN2_PROFILE/bin/plink2" export PYLMM_COMMAND="$GN2_PROFILE/bin/pylmm_redis" export GEMMA_COMMAND="$GN2_PROFILE/bin/gemma" diff --git a/etc/default_settings.py b/etc/default_settings.py index 1c5b10b4..1b609414 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -53,11 +53,13 @@ USE_REDIS = True # REDIS caching (note that redis will be phased out) USE_GN_SERVER = 'False' # Use GN_SERVER SQL calls HOME = os.environ['HOME'] +# ---- Default locations +GENENETWORK_FILES = HOME+"/gn2_data" # base dir for all static data files + # ---- Path overrides for Genenetwork - the defaults are normally # picked up from Guix or in the HOME directory # TMPDIR is normally picked up from the environment -# GENENETWORK_FILES = HOME+"/gn2_data" # base dir for all static data files # PRIVATE_FILES = HOME+"/gn2_private_data" # private static data files (unused) # ---- Local path to JS libraries - for development modules (only) -- cgit v1.2.3 From be458ca49557b93d2e5b8a0407d42f0a2fe9673f Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 9 Jun 2017 17:19:36 +0000 Subject: - Changed the way the genofile is set so different genofiles can be selected for mapping - Now shows error page for Correlation Matrix if traits aren't all from the same group (later need to make it check for shared samples, since different groups may contain some of the same samples - Mapping results page now displays the genofile in the information section - Only show Interval Analyst if species is mouse or rat (previously it would show a blank table for other species) - Network Graph now only shows links in a node's info if the relevant information (for example geneid) exists, and the label changes depending on the type of data set - Other minor changes to the appearance of the Network Graph menu (less white space, plus clickable descriptions for a couple options) - Improved Correlations Results page to shorten Description and Authors cell content for Phenotype traits (to keep table width manageable) - Changed the glossary links for LRS and Additive Effect columns for Gene Global Search - Improved appearance for Phenotype Global Search results - Temporarily removed Mapping options/features that don't work from the trait page --- wqflask/base/data_set.py | 7 +- .../wqflask/correlation_matrix/show_corr_matrix.py | 163 +++++++++++---------- .../wqflask/marker_regression/marker_regression.py | 11 +- .../marker_regression/marker_regression_gn1.py | 2 + wqflask/wqflask/network_graph/network_graph.py | 22 ++- wqflask/wqflask/static/new/css/network_graph.css | 1 - .../wqflask/static/new/javascript/network_graph.js | 16 +- wqflask/wqflask/templates/correlation_matrix.html | 16 +- wqflask/wqflask/templates/correlation_page.html | 13 +- wqflask/wqflask/templates/empty_collection.html | 15 -- wqflask/wqflask/templates/gsearch_gene.html | 12 +- wqflask/wqflask/templates/gsearch_pheno.html | 76 +++++----- .../wqflask/templates/marker_regression_gn1.html | 13 +- wqflask/wqflask/templates/network_graph.html | 23 ++- .../templates/show_trait_mapping_tools.html | 26 +--- 15 files changed, 213 insertions(+), 203 deletions(-) delete mode 100644 wqflask/wqflask/templates/empty_collection.html diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 4959457a..dbdbb51c 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -169,7 +169,7 @@ def mescape(*items): class Markers(object): """Todo: Build in cacheing so it saves us reading the same file more than once""" def __init__(self, name): - json_data_fh = open(locate(name + '.json','genotype/json')) + json_data_fh = open(locate(name + ".json",'genotype/json')) try: markers = json.load(json_data_fh) except: @@ -334,7 +334,10 @@ class DatasetGroup(object): else: marker_class = Markers - self.markers = marker_class(self.name) + if self.genofile: + self.markers = marker_class(self.genofile[:-5]) + else: + self.markers = marker_class(self.name) def get_f1_parent_strains(self): try: diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 95a5f6a6..b34beb7b 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -72,7 +72,14 @@ class CorrelationMatrix(object): self.all_sample_list = [] self.traits = [] + self.insufficient_shared_samples = False + this_group = self.trait_list[0][1].group.name #ZS: Getting initial group name before verifying all traits are in the same group in the following loop for trait_db in self.trait_list: + if trait_db[1].group.name != this_group: + self.insufficient_shared_samples = True + break + else: + this_group = trait_db[1].group.name this_trait = trait_db[0] self.traits.append(this_trait) this_sample_data = this_trait.data @@ -81,100 +88,102 @@ class CorrelationMatrix(object): if sample not in self.all_sample_list: self.all_sample_list.append(sample) - self.sample_data = [] - for trait_db in self.trait_list: - this_trait = trait_db[0] - this_sample_data = this_trait.data - - this_trait_vals = [] - for sample in self.all_sample_list: - if sample in this_sample_data: - this_trait_vals.append(this_sample_data[sample].value) - else: - this_trait_vals.append('') - self.sample_data.append(this_trait_vals) + if self.insufficient_shared_samples: + pass + else: + self.sample_data = [] + for trait_db in self.trait_list: + this_trait = trait_db[0] + this_sample_data = this_trait.data - if len(this_trait_vals) < len(self.trait_list): #Shouldn't do PCA if there are more traits than observations/samples - return False + this_trait_vals = [] + for sample in self.all_sample_list: + if sample in this_sample_data: + this_trait_vals.append(this_sample_data[sample].value) + else: + this_trait_vals.append('') + self.sample_data.append(this_trait_vals) - self.lowest_overlap = 8 #ZS: Variable set to the lowest overlapping samples in order to notify user, or 8, whichever is lower (since 8 is when we want to display warning) + if len(this_trait_vals) < len(self.trait_list): #Shouldn't do PCA if there are more traits than observations/samples + return False - self.corr_results = [] - self.pca_corr_results = [] - self.trait_data_array = [] - for trait_db in self.trait_list: - this_trait = trait_db[0] - this_db = trait_db[1] + self.lowest_overlap = 8 #ZS: Variable set to the lowest overlapping samples in order to notify user, or 8, whichever is lower (since 8 is when we want to display warning) - this_db_samples = this_db.group.all_samples_ordered() - this_sample_data = this_trait.data + self.corr_results = [] + self.pca_corr_results = [] + self.trait_data_array = [] + for trait_db in self.trait_list: + this_trait = trait_db[0] + this_db = trait_db[1] - this_trait_vals = [] - for index, sample in enumerate(this_db_samples): - if (sample in this_sample_data): - sample_value = this_sample_data[sample].value - this_trait_vals.append(sample_value) - self.trait_data_array.append(this_trait_vals) - - corr_result_row = [] - pca_corr_result_row = [] - is_spearman = False #ZS: To determine if it's above or below the diagonal - for target in self.trait_list: - target_trait = target[0] - target_db = target[1] - target_samples = target_db.group.all_samples_ordered() - target_sample_data = target_trait.data + this_db_samples = this_db.group.all_samples_ordered() + this_sample_data = this_trait.data this_trait_vals = [] - target_vals = [] - for index, sample in enumerate(target_samples): - if (sample in this_sample_data) and (sample in target_sample_data): + for index, sample in enumerate(this_db_samples): + if (sample in this_sample_data): sample_value = this_sample_data[sample].value - target_sample_value = target_sample_data[sample].value this_trait_vals.append(sample_value) - target_vals.append(target_sample_value) - - this_trait_vals, target_vals, num_overlap = corr_result_helpers.normalize_values(this_trait_vals, target_vals) - - if num_overlap < self.lowest_overlap: - self.lowest_overlap = num_overlap - if num_overlap == 0: - corr_result_row.append([target_trait, 0, num_overlap]) - pca_corr_result_row.append(0) - else: - pearson_r, pearson_p = scipy.stats.pearsonr(this_trait_vals, target_vals) - if is_spearman == False: - sample_r, sample_p = pearson_r, pearson_p - if sample_r == 1: - is_spearman = True + self.trait_data_array.append(this_trait_vals) + + corr_result_row = [] + pca_corr_result_row = [] + is_spearman = False #ZS: To determine if it's above or below the diagonal + for target in self.trait_list: + target_trait = target[0] + target_db = target[1] + target_samples = target_db.group.all_samples_ordered() + target_sample_data = target_trait.data + + this_trait_vals = [] + target_vals = [] + for index, sample in enumerate(target_samples): + if (sample in this_sample_data) and (sample in target_sample_data): + sample_value = this_sample_data[sample].value + target_sample_value = target_sample_data[sample].value + this_trait_vals.append(sample_value) + target_vals.append(target_sample_value) + + this_trait_vals, target_vals, num_overlap = corr_result_helpers.normalize_values(this_trait_vals, target_vals) + + if num_overlap < self.lowest_overlap: + self.lowest_overlap = num_overlap + if num_overlap == 0: + corr_result_row.append([target_trait, 0, num_overlap]) + pca_corr_result_row.append(0) else: - sample_r, sample_p = scipy.stats.spearmanr(this_trait_vals, target_vals) - - corr_result_row.append([target_trait, sample_r, num_overlap]) - pca_corr_result_row.append(pearson_r) + pearson_r, pearson_p = scipy.stats.pearsonr(this_trait_vals, target_vals) + if is_spearman == False: + sample_r, sample_p = pearson_r, pearson_p + if sample_r == 1: + is_spearman = True + else: + sample_r, sample_p = scipy.stats.spearmanr(this_trait_vals, target_vals) - self.corr_results.append(corr_result_row) - self.pca_corr_results.append(pca_corr_result_row) + corr_result_row.append([target_trait, sample_r, num_overlap]) + pca_corr_result_row.append(pearson_r) - corr_result_eigen = la.eigenvectors(numarray.array(self.pca_corr_results)) - corr_eigen_value, corr_eigen_vectors = sortEigenVectors(corr_result_eigen) + self.corr_results.append(corr_result_row) + self.pca_corr_results.append(pca_corr_result_row) - groups = [] - for sample in self.all_sample_list: - groups.append(1) + corr_result_eigen = la.eigenvectors(numarray.array(self.pca_corr_results)) + corr_eigen_value, corr_eigen_vectors = sortEigenVectors(corr_result_eigen) - pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors) + groups = [] + for sample in self.all_sample_list: + groups.append(1) - self.loadings_array = self.process_loadings() + pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors) - self.js_data = dict(traits = [trait.name for trait in self.traits], - groups = groups, - cols = range(len(self.traits)), - rows = range(len(self.traits)), - samples = self.all_sample_list, - sample_data = self.sample_data,) - # corr_results = [result[1] for result in result_row for result_row in self.corr_results]) + self.loadings_array = self.process_loadings() + self.js_data = dict(traits = [trait.name for trait in self.traits], + groups = groups, + cols = range(len(self.traits)), + rows = range(len(self.traits)), + samples = self.all_sample_list, + sample_data = self.sample_data,) + # corr_results = [result[1] for result in result_row for result_row in self.corr_results]) def get_trait_db_obs(self, trait_db_list): diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index 8882c515..60424468 100644 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -148,6 +148,10 @@ class MarkerRegression(object): self.showGenes = "ON" self.viewLegend = "ON" + if 'genofile' in start_vars: + if start_vars['genofile'] != "": + self.genofile_string = start_vars['genofile'] + self.dataset.group.genofile = self.genofile_string.split(":")[0] self.dataset.group.get_markers() if self.mapping_method == "gemma": self.score_type = "-log(p)" @@ -162,11 +166,10 @@ class MarkerRegression(object): self.mapping_scale = "morgan" self.control_marker = start_vars['control_marker'] self.do_control = start_vars['do_control'] - self.dataset.group.genofile = start_vars['genofile'] self.method = start_vars['mapmethod_rqtl_geno'] self.model = start_vars['mapmodel_rqtl_geno'] - if start_vars['pair_scan'] == "true": - self.pair_scan = True + #if start_vars['pair_scan'] == "true": + # self.pair_scan = True if self.permCheck and self.num_perm > 0: self.perm_output, self.suggestive, self.significant, results = rqtl_mapping.run_rqtl_geno(self.vals, self.dataset, self.method, self.model, self.permCheck, self.num_perm, self.do_control, self.control_marker, self.manhattan_plot, self.pair_scan) else: @@ -198,7 +201,6 @@ class MarkerRegression(object): self.control_marker = start_vars['control_marker'] self.do_control = start_vars['do_control'] - self.dataset.group.genofile = start_vars['genofile'] logger.info("Running qtlreaper") results, self.json_data, self.perm_output, self.suggestive, self.significant, self.bootstrap_results = qtlreaper_mapping.gen_reaper_results(self.this_trait, self.dataset, @@ -217,7 +219,6 @@ class MarkerRegression(object): #results = self.run_plink() elif self.mapping_method == "pylmm": logger.debug("RUNNING PYLMM") - self.dataset.group.genofile = start_vars['genofile'] if self.num_perm > 0: self.run_permutations(str(temp_uuid)) results = self.gen_data(str(temp_uuid)) diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index 82a44796..d99ac074 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -171,6 +171,8 @@ class MarkerRegression(object): self.dataset = start_vars['dataset'] self.this_trait = start_vars['this_trait'] self.species = start_vars['species'] + if 'genofile_string' in start_vars: + self.genofile_string = start_vars['genofile_string'] #Needing for form submission when doing single chr mapping or remapping after changing options self.samples = start_vars['samples'] diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index cebe5c03..4ce6c48d 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -181,12 +181,21 @@ class NetworkGraph(object): self.edges_list.append(edge_dict) - node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), - 'label' : this_trait.name, - 'symbol' : this_trait.symbol, - 'geneid' : this_trait.geneid, - 'omim' : this_trait.omim, - 'max_corr' : max_corr } } + if trait_db[1].type == "ProbeSet": + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'label' : this_trait.symbol, + 'symbol' : this_trait.symbol, + 'geneid' : this_trait.geneid, + 'omim' : this_trait.omim, + 'max_corr' : max_corr } } + elif trait_db[1].type == "Publish": + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'label' : this_trait.name, + 'max_corr' : max_corr } } + else: + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'label' : this_trait.name, + 'max_corr' : max_corr } } self.nodes_list.append(node_dict) #self.network_data['dataSchema'] = {'nodes' : [{'name' : "label" , 'type' : "string"}], @@ -211,7 +220,6 @@ class NetworkGraph(object): # corr_results = [result[1] for result in result_row for result_row in self.corr_results]) def get_trait_db_obs(self, trait_db_list): - self.trait_list = [] for i, trait_db in enumerate(trait_db_list): if i == (len(trait_db_list) - 1): diff --git a/wqflask/wqflask/static/new/css/network_graph.css b/wqflask/wqflask/static/new/css/network_graph.css index 1cba546a..1a0bafeb 100644 --- a/wqflask/wqflask/static/new/css/network_graph.css +++ b/wqflask/wqflask/static/new/css/network_graph.css @@ -14,7 +14,6 @@ position: relative; float: left; width: 18.5em; - padding: 1em 1em 1em 1em; background: #fff url('/static/new/images/a1.gif') top right repeat-y; } diff --git a/wqflask/wqflask/static/new/javascript/network_graph.js b/wqflask/wqflask/static/new/javascript/network_graph.js index d1afd47c..731acf1a 100644 --- a/wqflask/wqflask/static/new/javascript/network_graph.js +++ b/wqflask/wqflask/static/new/javascript/network_graph.js @@ -12,7 +12,7 @@ window.onload=function() { selector: 'node', style: { 'background-color': '#666', - 'label': 'data(symbol)', + 'label': 'data(label )', 'font-size': 10 } }, @@ -81,10 +81,18 @@ window.onload=function() { function create_qtips(cy){ cy.nodes().qtip({ content: function(){ + qtip_content = '' gn_link = ''+''+this.data().id +''+'
    ' - ncbi_link = 'NCBI'+'
    ' - omim_link = '
    OMIM'+'
    ' - qtip_content = gn_link + ncbi_link + omim_link + qtip_content += gn_link + if (typeof(this.data().geneid) !== 'undefined'){ + ncbi_link = '
    NCBI'+'
    ' + qtip_content += ncbi_link + } + if (typeof(this.data().omim) !== 'undefined'){ + omim_link = '
    OMIM'+'
    ' + qtip_content += omim_link + } + //qtip_content = gn_link + ncbi_link + omim_link return qtip_content //return ''+'
    '+this.data().id +''+'' }, diff --git a/wqflask/wqflask/templates/correlation_matrix.html b/wqflask/wqflask/templates/correlation_matrix.html index eb675568..ab793d58 100644 --- a/wqflask/wqflask/templates/correlation_matrix.html +++ b/wqflask/wqflask/templates/correlation_matrix.html @@ -64,21 +64,15 @@

    Factor Loadings Plot

    -
    - +

    Factor Loadings Table

    -
      {{ loop.index }} {{ trait.location_repr }}{{ trait.location_repr }} {{ '%0.3f' % trait.mean|float }} {% if trait.LRS_score_repr != "N/A" %}{{ '%0.1f' % trait.LRS_score_repr|float }}{% else %}N/A{% endif %} {{ trait.LRS_location_repr }}
    +
    - - - {% if trait_list|length > 2 %}{% endif %} - + + + {% if trait_list|length > 2 %}{% endif %} diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index fbf373f6..fa9e3585 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -383,8 +383,8 @@ { "type": "natural" }, { "type": "natural" }, { "type": "natural" }, - { "type": "natural", "width": "25%" }, - { "type": "natural", "width": "15%" }, + { "type": "natural", "width": "20%" }, + { "type": "natural", "width": "12%" }, { "type": "natural" }, { "type": "natural" }, { "type": "natural" }, @@ -394,9 +394,14 @@ { "type": "scientific" } ], "createdRow": function ( row, data, index ) { + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 50) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 50)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') + } $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - if ($('td', row).eq(4).text().length > 60) { - $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 60)); + if ($('td', row).eq(4).text().length > 40) { + $('td', row).eq(4).text($('td', row).eq(4).text().substring(0, 40)); $('td', row).eq(4).text($('td', row).eq(4).text() + '...') } }, diff --git a/wqflask/wqflask/templates/empty_collection.html b/wqflask/wqflask/templates/empty_collection.html deleted file mode 100644 index 3f2b3786..00000000 --- a/wqflask/wqflask/templates/empty_collection.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "base.html" %} -{% block title %}{{ tool }}{% endblock %} -{% block content %} - - {{ header("Error") }} - -
    - -

    You must select at least one trait to use the {{ tool }}.

    -
    - - - - -{% endblock %} diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index e8bb6337..c1f039c7 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -42,9 +42,9 @@
    - + - + @@ -80,9 +80,9 @@ - - - + + +
    Factor 1Factor 2Factor 3Factor 1Factor 2Factor 3
    Description Location MeanMax LRS ?Max LRS Max LRS LocationAdditive ?Additive Effect
    Description Location MeanMax LRS ?Max LRS LocationAdditive ?Max LRS Max LRS LocationAdditive Effect
    @@ -102,8 +102,6 @@ - - - - - - - - - - - - - - - +{% extends "base.html" %} +{% block title %}Heatmap{% endblock %} +{% block css %} + + +{% endblock %} +{% block content %} + + {{ header("Heatmap") }} + +
    +
    +

    + The following heatmap is a work in progress. The heatmap for each trait runs horizontally (as opposed to vertically in GeneNetwork 1), + and hovering over a given trait's heatmap track will display its corresponding QTL chart below. Black on the heatmap corresponds with a + low positive or negative z-score (darker when closer to 0), while light blue and yellow correspond to high negative and positive z-scores respectively. +

    +
    +
    +
    + +
    +
    + +
    + + + +{% endblock %} + +{% block js %} + + + + + + + + + + + + {% endblock %} \ No newline at end of file -- cgit v1.2.3 From 3d1d8839d38d0552ba110de9ea467b83f72069fd Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 13 Jun 2017 16:25:06 +0000 Subject: Fixed minor issue where the part of the legend describing the LRS/LOD line still appeared for manhattan plots --- wqflask/wqflask/marker_regression/marker_regression_gn1.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index d99ac074..74474cb0 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -1052,7 +1052,10 @@ class MarkerRegression(object): startPosY = 15 nCol = 2 smallLabelFont = pid.Font(ttf="trebuc", size=12*fontZoom, bold=1) - leftOffset = xLeftOffset+(nCol-1)*200*fontZoom + if self.manhattan_plot: + leftOffset = xLeftOffset + else: + leftOffset = xLeftOffset+(nCol-1)*200*fontZoom canvas.drawPolygon(((leftOffset+6, startPosY-6), (leftOffset, startPosY+6), (leftOffset+12, startPosY+6)), edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) canvas.drawString("Sequence Site", (leftOffset+15), (startPosY+5), smallLabelFont, self.TOP_RIGHT_INFO_COLOR) @@ -1143,9 +1146,10 @@ class MarkerRegression(object): labelFont=pid.Font(ttf="trebuc",size=12*fontZoom, bold=1) startPosY = 15 stepPosY = 12*fontZoom - canvas.drawLine(xLeftOffset,startPosY,xLeftOffset+32,startPosY,color=self.LRS_COLOR, width=2) - canvas.drawString(self.LRS_LOD, xLeftOffset+40,startPosY+5,font=labelFont,color=pid.black) - startPosY += stepPosY + if self.manhattan_plot != True: + canvas.drawLine(xLeftOffset,startPosY,xLeftOffset+32,startPosY,color=self.LRS_COLOR, width=2) + canvas.drawString(self.LRS_LOD, xLeftOffset+40,startPosY+5,font=labelFont,color=pid.black) + startPosY += stepPosY if self.additiveChecked: startPosX = xLeftOffset -- cgit v1.2.3 From 3977687e3613e71705e7ffcc894c51f166f46820 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 13 Jun 2017 17:15:56 +0000 Subject: Fixed issue that caused haplotype analyst to no longer work Fixed Results table for centimorgan results to display cM instead of Mb --- .../wqflask/marker_regression/marker_regression_gn1.py | 4 ++-- wqflask/wqflask/templates/marker_regression_gn1.html | 17 +++++++++++------ wqflask/wqflask/views.py | 1 + 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index 74474cb0..08332e7d 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -447,7 +447,7 @@ class MarkerRegression(object): if self.haplotypeAnalystChecked and self.selectedChr > -1: #thisTrait = self.traitList[0] thisTrait = self.this_trait - _strains, _vals, _vars = thisTrait.export_informative() + _strains, _vals, _vars, _aliases = thisTrait.export_informative() smd=[] for ii, _val in enumerate(_vals): temp = GeneralObject(name=_strains[ii], value=_val) @@ -1440,7 +1440,7 @@ class MarkerRegression(object): #thisTrait = self.traitList[0] thisTrait = self.this_trait - _strains, _vals, _vars = thisTrait.export_informative() + _strains, _vals, _vars, _aliases = thisTrait.export_informative() smd=[] for ii, _val in enumerate(_vals): diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/marker_regression_gn1.html index ae922389..5afd134a 100644 --- a/wqflask/wqflask/templates/marker_regression_gn1.html +++ b/wqflask/wqflask/templates/marker_regression_gn1.html @@ -174,7 +174,7 @@ {% if selectedChr == -1 %} -
    +

    Results

    @@ -185,7 +185,7 @@ - {% if plotScale == "centimorgan" %} + {% if plotScale != "physic" %} {% else %} @@ -222,7 +222,11 @@ {% endif %} {% endif %} + {% if plotScale != "physic" %} + + {% else %} + {% endif %} {% if 'additive' in marker %} {% endif %} @@ -235,8 +239,8 @@
    Locus {{ LRS_LOD }} ChrcMMb{{marker.chr}}{{ '%0.3f' | format(marker.Mb|float) }}{{ '%0.6f' | format(marker.Mb|float) }}{{ '%0.3f' | format(marker.additive|float) }}
    - {% elif selectedChr != -1 and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %} -
    + {% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %} +

    Interval Analyst

    @@ -350,9 +354,10 @@ "order": [[3, "asc" ]], "sDom": "RZtir", "iDisplayLength": -1, - "bDeferRender": true, + "autoWidth": false, + "deferRender": true, "bSortClasses": false, - "scrollY": true, + "scrollY": "600px", "scrollCollapse": false, "paging": false } ); diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index ca7f04e9..83496000 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -558,6 +558,7 @@ def marker_regression_page(): 'selected_chr', 'chromosomes', 'mapping_scale', + 'plotScale', 'score_type', 'suggestive', 'significant', -- cgit v1.2.3 From f13cf491ac849c9ca484a204cc25d9493f36d781 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 13 Jun 2017 18:31:38 +0000 Subject: Added to border to table footer in search results --- wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css | 1 + 1 file changed, 1 insertion(+) diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css index ab7420a6..a5b9f09c 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css @@ -42,6 +42,7 @@ table.dataTable tfoot td { color: #000000; background-color: #ffffff; border-collapse: collapse; + border-top: #cccccc 2px solid; //padding: 0; padding: 10px 18px 6px 18px; //border-top: 1px solid #111; -- cgit v1.2.3 From ecd573cc7e150805383d9cdbd41f1b136c9afc0e Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 13 Jun 2017 18:45:11 +0000 Subject: Fixed trait links in network graph nodes Added warning notifying users that file upload option in the submit_trait page doesn't work yet --- wqflask/wqflask/network_graph/network_graph.py | 6 ++++++ wqflask/wqflask/static/new/javascript/network_graph.js | 2 +- wqflask/wqflask/templates/submit_trait.html | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index 4ce6c48d..7eb5be61 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -183,6 +183,8 @@ class NetworkGraph(object): if trait_db[1].type == "ProbeSet": node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'name' : str(this_trait.name), + 'dataset' : str(this_trait.dataset.name), 'label' : this_trait.symbol, 'symbol' : this_trait.symbol, 'geneid' : this_trait.geneid, @@ -190,10 +192,14 @@ class NetworkGraph(object): 'max_corr' : max_corr } } elif trait_db[1].type == "Publish": node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'name' : str(this_trait.name), + 'dataset' : str(this_trait.dataset.name), 'label' : this_trait.name, 'max_corr' : max_corr } } else: node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), + 'name' : str(this_trait.name), + 'dataset' : str(this_trait.dataset.name), 'label' : this_trait.name, 'max_corr' : max_corr } } self.nodes_list.append(node_dict) diff --git a/wqflask/wqflask/static/new/javascript/network_graph.js b/wqflask/wqflask/static/new/javascript/network_graph.js index 731acf1a..03ef1c98 100644 --- a/wqflask/wqflask/static/new/javascript/network_graph.js +++ b/wqflask/wqflask/static/new/javascript/network_graph.js @@ -82,7 +82,7 @@ window.onload=function() { cy.nodes().qtip({ content: function(){ qtip_content = '' - gn_link = ''+''+this.data().id +''+'
    ' + gn_link = ''+''+this.data().id +''+'
    ' qtip_content += gn_link if (typeof(this.data().geneid) !== 'undefined'){ ncbi_link = 'NCBI'+'
    ' diff --git a/wqflask/wqflask/templates/submit_trait.html b/wqflask/wqflask/templates/submit_trait.html index 8d624ffd..e93c1c9d 100644 --- a/wqflask/wqflask/templates/submit_trait.html +++ b/wqflask/wqflask/templates/submit_trait.html @@ -56,6 +56,7 @@

    2. Enter Trait Data:

    +

    WARNING: File uploading isn't enabled yet, so please paste your values using the second option.


    -- cgit v1.2.3 From ee6e8504e0c6e24d75f9ea939b1e48762dcfc977 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 14 Jun 2017 18:40:35 +0000 Subject: Added descriptions for GEMMA and PLINK as well as a warning about the issue with GEMMA where you can't run it simultaneously on two traits from the same group --- wqflask/wqflask/templates/show_trait_mapping_tools.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index d8a18f38..bded60d2 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -341,6 +341,7 @@
    + {% if dataset.group.mapping_id == "1" %}
    Interval Mapping
    Interval mapping is a process in which the statistical significance of a hypothetical QTL is evaluated at regular points across a chromosome, even in the absence of explicit genotype data at those points.
    @@ -349,6 +350,17 @@
    R/qtl
    R/qtl is an extensible, interactive environment for mapping quantitative trait loci (QTL) in experimental crosses.
    + {% else %} +
    +
    GEMMA
    +
    + GEMMA is software implementing the Genome-wide Efficient Mixed Model Association algorithm for a standard linear mixed model for genome-wide association studies (GWAS).
    + Note: There currently exists an issue where GEMMA can't be run on traits from the same group simultaneously. If you recieve an error, please wait a few minutes and try again. +
    +
    PLINK
    +
    PLINK is a free, open-source whole genome association analysis toolset.
    +
    + {% endif %}
    --> + {% if g.user_session.user_ob %}
    @@ -146,7 +147,7 @@
    - {% endif %} + {% endif %}--> -- cgit v1.2.3 From adbdd62dfe4817b9d4bb6021f73de694199810b7 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 14 Jun 2017 23:16:28 +0000 Subject: Changed color scale for heatmap to blue <-> white <-> red Removed an extraneous character in the gsearch_pheno html --- wqflask/wqflask/static/new/javascript/lodheatmap.js | 2 +- wqflask/wqflask/templates/gsearch_pheno.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/lodheatmap.js b/wqflask/wqflask/static/new/javascript/lodheatmap.js index 45feb75d..f604cd10 100644 --- a/wqflask/wqflask/static/new/javascript/lodheatmap.js +++ b/wqflask/wqflask/static/new/javascript/lodheatmap.js @@ -20,7 +20,7 @@ lodheatmap = function() { chrGap = 8; titlepos = 20; rectcolor = d3.rgb(230, 230, 230); - colors = ["slateblue", "black", "yellow"]; + colors = ["blue", "white", "crimson"]; title = ""; xlab = "Chromosome"; ylab = ""; diff --git a/wqflask/wqflask/templates/gsearch_pheno.html b/wqflask/wqflask/templates/gsearch_pheno.html index 1bb2120e..46a80a09 100644 --- a/wqflask/wqflask/templates/gsearch_pheno.html +++ b/wqflask/wqflask/templates/gsearch_pheno.html @@ -27,7 +27,7 @@
    - v
    +
    -- cgit v1.2.3 From afd2028e0ddab64e433eceb19e8cbd8d7149e080 Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Mon, 26 Jun 2017 19:38:49 +0000 Subject: Fix Correlation Scatterplot things --- .../wqflask/static/new/css/corr_scatter_plot2.css | 20 ++-- .../new/javascript/draw_corr_scatterplot-2.js | 132 +++++++++++---------- wqflask/wqflask/templates/corr_scatterplot.html | 12 +- 3 files changed, 86 insertions(+), 78 deletions(-) diff --git a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css index 92e777c2..e21d828f 100644 --- a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css +++ b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css @@ -1,19 +1,25 @@ .nvd3 .nv-axis.nv-x text { - font-size: 16px; - font-weight: normal; - fill: black; + font-size: 17px; + font-weight: normal; + fill: black; } .nvd3 .nv-axis.nv-y text { - font-size: 16px; - font-weight: normal; - fill: black; + font-size: 17px; + font-weight: normal; + fill:black; } -.nv-y .tick.zero line { +.nv-x .nv-axis g path.domain { stroke: black; + stroke-width: 2; } .nv-y .nv-axis g path.domain { stroke: black; + stroke-width: 2; +} + +.nvd3 .nv-axis.nv-x path.domain { + stroke-opacity: 1; } diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js index 7a5a86bd..f88e7d5d 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js @@ -1,74 +1,76 @@ var chart; nv.addGraph(function() { - // - chart = nv.models.scatterChart(); - // - chart.showLegend(false); - chart.duration(300); - chart.color(d3.scale.category10().range()); - chart.pointRange([200,0]); - // - // chart.showDistX(true); - // chart.showDistY(true); - chart.xAxis.tickFormat(d3.format('.02f')); - chart.yAxis.tickFormat(d3.format('.02f')); - // chart.showXAxis(false); - // chart.showYAxis(false); - chart.xAxis.axisLabel(js_data.trait_1); - chart.yAxis.axisLabel(js_data.trait_2); - // - xmin = d3.min(js_data.data[0]); - xmax = d3.max(js_data.data[0]); - xrange = xmax - xmin; - ymin = d3.min(js_data.data[1]); - ymax = d3.max(js_data.data[1]); - yrange = ymax - ymin; - chart.xDomain([xmin - xrange/10, xmax + xrange/10]); - chart.yDomain([ymin - yrange/10, ymax + yrange/10]); - // - d3.select('#scatterplot2 svg').datum(nv.log(getdata())).call(chart); - nv.utils.windowResize(chart.update); - return chart; + // + chart = nv.models.scatterChart(); + // + chart.showLegend(false); + chart.duration(300); + chart.color(d3.scale.category10().range()); + chart.pointRange([200,0]); + // + chart.xAxis.tickFormat(d3.format('.02f')); + chart.yAxis.tickFormat(d3.format('.02f')); + chart.xAxis.axisLabel(js_data.trait_1); + chart.xAxis.axisLabelDistance(11); + chart.yAxis.axisLabel(js_data.trait_2); + chart.yAxis.axisLabelDistance(11); + // + xmin = d3.min(js_data.data[0]); + xmax = d3.max(js_data.data[0]); + xrange = xmax - xmin; + ymin = d3.min(js_data.data[1]); + ymax = d3.max(js_data.data[1]); + yrange = ymax - ymin; + chart.xDomain([xmin - xrange/10, xmax + xrange/10]); + chart.yDomain([ymin - yrange/10, ymax + yrange/10]); + // + chart.tooltip.contentGenerator(function (obj) { + return '(' + obj.point.x + ', ' + obj.point.y + ')'; + }); + // + d3.select('#scatterplot2 svg').datum(nv.log(getdata())).call(chart); + nv.utils.windowResize(chart.update); + return chart; }); function getdata () { - var data = []; - data.push({ - values: [], - slope: js_data.slope, - intercept: js_data.intercept - }); - for (j = 0; j < js_data.data[0].length; j++) { - data[0].values.push({ - x: js_data.data[0][j], - y: js_data.data[1][j], - size: 10, - shape: 'circle' - }); - } - return data; + var data = []; + data.push({ + values: [], + slope: js_data.slope, + intercept: js_data.intercept + }); + for (j = 0; j < js_data.data[0].length; j++) { + data[0].values.push({ + x: js_data.data[0][j], + y: js_data.data[1][j], + size: 10, + shape: 'circle' + }); + } + return data; } - + function randomData(groups, points) { - var data = [], - shapes = ['circle'], - random = d3.random.normal(); - for (i = 0; i < groups; i++) { - data.push({ - key: 'Group ' + i, - values: [], - slope: Math.random() - .01, - intercept: Math.random() - .5 - }); - for (j = 0; j < points; j++) { - data[i].values.push({ - x: random(), - y: random(), - size: Math.random(), - shape: shapes[j % shapes.length] - }); - } - } - return data; + var data = [], + shapes = ['circle'], + random = d3.random.normal(); + for (i = 0; i < groups; i++) { + data.push({ + key: 'Group ' + i, + values: [], + slope: Math.random() - .01, + intercept: Math.random() - .5 + }); + for (j = 0; j < points; j++) { + data[i].values.push({ + x: random(), + y: random(), + size: Math.random(), + shape: shapes[j % shapes.length] + }); + } + } + return data; } diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index 4464025e..f07568a0 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -55,11 +55,11 @@
    - - - - - + + + + +
    num overlap {{jsdata.num_overlap}}
    slope {{jsdata.slope}}
    intercept {{jsdata.intercept}}
    r value {{jsdata.r_value}}
    p value {{jsdata.p_value}}
    number {{jsdata.num_overlap}}
    slope {{'%0.3f' % jsdata.slope}}
    intercept {{'%0.3f' % jsdata.intercept}}
    r value {{'%0.3f' % jsdata.r_value}}
    p value {{'%0.3e' % jsdata.p_value}}
    @@ -85,7 +85,7 @@ -->
    - +

    -- cgit v1.2.3 From 3a7caecf4c7d30f693ba838e1983d03a742fe5ba Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Wed, 28 Jun 2017 17:02:38 +0000 Subject: Update Correlation Scatterplot --- .../wqflask/static/new/css/corr_scatter_plot2.css | 27 +++++++++++++++++----- .../new/javascript/draw_corr_scatterplot-2.js | 4 ++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css index e21d828f..5aa9b9bf 100644 --- a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css +++ b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css @@ -1,25 +1,40 @@ .nvd3 .nv-axis.nv-x text { - font-size: 17px; + font-size: 16px; font-weight: normal; fill: black; } .nvd3 .nv-axis.nv-y text { - font-size: 17px; + font-size: 16px; font-weight: normal; fill:black; } .nv-x .nv-axis g path.domain { - stroke: black; - stroke-width: 2; + stroke: black; + stroke-width: 2; } .nv-y .nv-axis g path.domain { - stroke: black; - stroke-width: 2; + stroke: black; + stroke-width: 2; } .nvd3 .nv-axis.nv-x path.domain { stroke-opacity: 1; } + +.nvd3 .nv-axis.nv-y path.domain { + stroke-opacity: 1; +} + +line.nv-regLine { + stroke: red !important; +} + +.nv-axisMin-x, +.nv-axisMax-x, +.nv-axisMin-y, +.nv-axisMax-y { + display: none; +} diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js index f88e7d5d..ad6c7d6b 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js @@ -9,8 +9,8 @@ nv.addGraph(function() { chart.color(d3.scale.category10().range()); chart.pointRange([200,0]); // - chart.xAxis.tickFormat(d3.format('.02f')); - chart.yAxis.tickFormat(d3.format('.02f')); + chart.xAxis.tickFormat(d3.format('r')); + chart.yAxis.tickFormat(d3.format('r')); chart.xAxis.axisLabel(js_data.trait_1); chart.xAxis.axisLabelDistance(11); chart.yAxis.axisLabel(js_data.trait_2); -- cgit v1.2.3 From bb67456364bda733bbe1eab80ab0ba9d44fa7daa Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Thu, 29 Jun 2017 20:40:43 +0000 Subject: Update Correlation Scatterplot --- wqflask/wqflask/templates/corr_scatterplot.html | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index f07568a0..05891c95 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -53,16 +53,6 @@

    Correlation Scatterplot

    - - - - - - - - -
    number {{jsdata.num_overlap}}
    slope {{'%0.3f' % jsdata.slope}}
    intercept {{'%0.3f' % jsdata.intercept}}
    r value {{'%0.3f' % jsdata.r_value}}
    p value {{'%0.3e' % jsdata.p_value}}
    - @@ -119,7 +119,8 @@
    - {% if g.user_session.user_ob %}
    @@ -147,7 +149,7 @@
    - {% endif %}--> + {% endif %}
    -- cgit v1.2.3 From 255aace685b7919808e93ad3c8c47334b0496eb9 Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Wed, 2 Aug 2017 22:45:45 +0000 Subject: Update Correlation Scatterplot parameters --- .../wqflask/static/new/css/corr_scatter_plot2.css | 5 +- .../new/javascript/draw_corr_scatterplot-2.js | 93 +++++++++++++--- wqflask/wqflask/templates/corr_scatterplot.html | 119 ++++++++++++--------- 3 files changed, 152 insertions(+), 65 deletions(-) diff --git a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css index 5aa9b9bf..a2ebb252 100644 --- a/wqflask/wqflask/static/new/css/corr_scatter_plot2.css +++ b/wqflask/wqflask/static/new/css/corr_scatter_plot2.css @@ -7,7 +7,7 @@ .nvd3 .nv-axis.nv-y text { font-size: 16px; font-weight: normal; - fill:black; + fill: black; } .nv-x .nv-axis g path.domain { @@ -29,7 +29,8 @@ } line.nv-regLine { - stroke: red !important; + stroke: red; + stroke-width: 1; } .nv-axisMin-x, diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js index 96763aca..1fb17bf0 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js @@ -1,13 +1,14 @@ var chart; -nv.addGraph(function() { +function drawg () { // chart = nv.models.scatterChart(); // chart.showLegend(false); chart.duration(300); chart.color(d3.scale.category10().range()); - chart.pointRange([200,0]); + chart.pointRange([0, 400]); + chart.pointDomain([0, 10]); // chart.xAxis.axisLabel(js_data.trait_1); chart.xAxis.axisLabelDistance(11); @@ -26,15 +27,12 @@ nv.addGraph(function() { chart.yAxis.tickFormat(d3.format(checkformat(yrange))); // chart.tooltip.contentGenerator(function (obj) { - return '(' + obj.point.x + ', ' + obj.point.y + ')'; + // return '(' + obj.point.x + ', ' + obj.point.y + ')'; + return '(' + obj.point.name + ')'; }); - // - d3.select('#scatterplot2 svg').datum(nv.log(getdata())).call(chart); - nv.utils.windowResize(chart.update); - return chart; -}); +} -function getdata () { +function getdata(size, shape) { var data = []; data.push({ values: [], @@ -45,14 +43,15 @@ function getdata () { data[0].values.push({ x: js_data.data[0][j], y: js_data.data[1][j], - size: 10, - shape: 'circle' + name: js_data.indIDs[j], + size: size, + shape: shape }); } return data; } -function checkformat (range) { +function checkformat(range) { cell = range / 10.0; if (cell >= 1) { return ",r"; @@ -62,3 +61,73 @@ function checkformat (range) { return ",.0" + n + "f"; } } + +function chartupdate() { + // + var axisxcolor = $("#axisxcolor").val(); + $(".nvd3 .nv-axis.nv-x text").css("fill", axisxcolor); + // + var axisycolor = $("#axisycolor").val(); + $(".nvd3 .nv-axis.nv-y text").css("fill", axisycolor); + // + var axisxfont = $("#axisxfont").val(); + $(".nvd3 .nv-axis.nv-x text").css("font-size", axisxfont); + // + var axisyfont = $("#axisyfont").val(); + $(".nvd3 .nv-axis.nv-y text").css("font-size", axisyfont); + // + var domainxcolor = $("#domainxcolor").val(); + $(".nv-x .nv-axis g path.domain").css("stroke", domainxcolor); + // + var domainycolor = $("#domainycolor").val(); + $(".nv-y .nv-axis g path.domain").css("stroke", domainycolor); + // + var domainxwidth = $("#domainxwidth").val(); + $(".nv-x .nv-axis g path.domain").css("stroke-width", domainxwidth); + // + var domainywidth = $("#domainywidth").val(); + $(".nv-y .nv-axis g path.domain").css("stroke-width", domainywidth); + // + var clinecolor = $("#clinecolor").val(); + $("line.nv-regLine").css("stroke", clinecolor); + // + var clinewidth = $("#clinewidth").val(); + $("line.nv-regLine").css("stroke-width", clinewidth); +} + +function chartupdatewh() { + // + var width = $("#width").val(); + $("#scatterplot2 svg").css("width", width); + // + var height = $("#height").val(); + $("#scatterplot2 svg").css("height", height); + // + window.dispatchEvent(new Event('resize')); +} + +function chartupdatedata() { + // + var size = $("#marksize").val(); + var shape = $("#markshape").val(); + // + d3.select('#scatterplot2 svg').datum(nv.log(getdata(size, shape))).call(chart); + nv.utils.windowResize(chart.update); +} + +drawg(); +chartupdate(); +chartupdatewh(); +chartupdatedata(); + +$(".chartupdate").change(function () { + chartupdate(); +}); + +$(".chartupdatewh").change(function () { + chartupdatewh(); +}); + +$(".chartupdatedata").change(function () { + chartupdatedata(); +}); diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index b4525718..b62df32f 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -12,67 +12,84 @@ {% endblock %} {% block content %} - +

    Correlation Scatterplot

    -
    -- cgit v1.2.3 From e172f74ff8cc76ae43dc740d20d3eaafce71b284 Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Wed, 2 Aug 2017 22:56:22 +0000 Subject: Remove duplicate codes --- wqflask/wqflask/templates/corr_scatterplot.html | 39 ------------------------- 1 file changed, 39 deletions(-) diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index d25a361d..47b83018 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -97,45 +97,6 @@
    -

    Correlation Scatterplot

    - - - - - - - - - -
    num overlap {{jsdata.num_overlap}}
    slope {{jsdata.slope}}
    intercept {{jsdata.intercept}}
    r value {{jsdata.r_value}}
    p value {{jsdata.p_value}}
    - - - -
    - -
    - -
    -
    {% if trait_1.dataset.type == "ProbeSet" %} -- cgit v1.2.3 From f82a8114d973d4e85c8c38eecceff86aec55eed9 Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Thu, 3 Aug 2017 17:50:18 +0000 Subject: remove brackets --- wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js index 1fb17bf0..17f939cc 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js @@ -28,7 +28,7 @@ function drawg () { // chart.tooltip.contentGenerator(function (obj) { // return '(' + obj.point.x + ', ' + obj.point.y + ')'; - return '(' + obj.point.name + ')'; + return '' + obj.point.name + ''; }); } -- cgit v1.2.3 From 28a128b242af78941b7511e8f84ca5d61a19997c Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Wed, 23 Aug 2017 15:26:26 +0000 Subject: Update corr scatterplot --- wqflask/wqflask/correlation/corr_scatter_plot.py | 15 ++ .../new/javascript/draw_corr_scatterplot-2_sr.js | 133 ++++++++++++ wqflask/wqflask/templates/corr_scatterplot.html | 239 ++++++++++++++------- 3 files changed, 315 insertions(+), 72 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js diff --git a/wqflask/wqflask/correlation/corr_scatter_plot.py b/wqflask/wqflask/correlation/corr_scatter_plot.py index 6a92c501..a08cd759 100644 --- a/wqflask/wqflask/correlation/corr_scatter_plot.py +++ b/wqflask/wqflask/correlation/corr_scatter_plot.py @@ -67,9 +67,17 @@ class CorrScatterPlot(object): x = np.array(vals_1) y = np.array(vals_2) slope, intercept, r_value, p_value, std_err = stats.linregress(x, y) + + rx = stats.rankdata(x) + ry = stats.rankdata(y) + self.rdata = [] + self.rdata.append(rx.tolist()) + self.rdata.append(ry.tolist()) + srslope, srintercept, srr_value, srp_value, srstd_err = stats.linregress(rx, ry) self.js_data = dict( data = self.data, + rdata = self.rdata, indIDs = self.indIDs, trait_1 = self.trait_1.dataset.name + ": " + str(self.trait_1.name), trait_2 = self.trait_2.dataset.name + ": " + str(self.trait_2.name), @@ -78,10 +86,17 @@ class CorrScatterPlot(object): num_overlap = num_overlap, vals_1 = vals_1, vals_2 = vals_2, + slope = slope, intercept = intercept, r_value = r_value, p_value = p_value, + + srslope = srslope, + srintercept = srintercept, + srr_value = srr_value, + srp_value = srp_value, + width = width, height = height, circle_color = circle_color, diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js new file mode 100644 index 00000000..08ddc825 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2_sr.js @@ -0,0 +1,133 @@ +var srchart; + +function srdrawg () { + // + srchart = nv.models.scatterChart(); + // + srchart.showLegend(false); + srchart.duration(300); + srchart.color(d3.scale.category10().range()); + srchart.pointRange([0, 400]); + srchart.pointDomain([0, 10]); + // + srchart.xAxis.axisLabel(js_data.trait_1); + srchart.xAxis.axisLabelDistance(11); + srchart.yAxis.axisLabel(js_data.trait_2); + srchart.yAxis.axisLabelDistance(11); + // + xmin = d3.min(js_data.rdata[0]); + xmax = d3.max(js_data.rdata[0]); + xrange = xmax - xmin; + ymin = d3.min(js_data.rdata[1]); + ymax = d3.max(js_data.rdata[1]); + yrange = ymax - ymin; + srchart.xDomain([xmin - xrange/10, xmax + xrange/10]); + srchart.yDomain([ymin - yrange/10, ymax + yrange/10]); + srchart.xAxis.tickFormat(d3.format(srcheckformat(xrange))); + srchart.yAxis.tickFormat(d3.format(srcheckformat(yrange))); + // + srchart.tooltip.contentGenerator(function (obj) { + // return '(' + obj.point.x + ', ' + obj.point.y + ')'; + return '' + obj.point.name + ''; + }); +} + +function srgetdata(size, shape) { + var data = []; + data.push({ + values: [], + slope: js_data.srslope, + intercept: js_data.srintercept + }); + for (j = 0; j < js_data.rdata[0].length; j++) { + data[0].values.push({ + x: js_data.rdata[0][j], + y: js_data.rdata[1][j], + name: js_data.indIDs[j], + size: size, + shape: shape + }); + } + return data; +} + +function srcheckformat(range) { + cell = range / 10.0; + if (cell >= 1) { + return ",r"; + } else { + cell = -Math.log(cell); + n = cell.toString().split(".")[0].length; + return ",.0" + n + "f"; + } +} + +function srchartupdate() { + // + var axisxcolor = $("#axisxcolor").val(); + $(".nvd3 .nv-axis.nv-x text").css("fill", axisxcolor); + // + var axisycolor = $("#axisycolor").val(); + $(".nvd3 .nv-axis.nv-y text").css("fill", axisycolor); + // + var axisxfont = $("#axisxfont").val(); + $(".nvd3 .nv-axis.nv-x text").css("font-size", axisxfont); + // + var axisyfont = $("#axisyfont").val(); + $(".nvd3 .nv-axis.nv-y text").css("font-size", axisyfont); + // + var domainxcolor = $("#domainxcolor").val(); + $(".nv-x .nv-axis g path.domain").css("stroke", domainxcolor); + // + var domainycolor = $("#domainycolor").val(); + $(".nv-y .nv-axis g path.domain").css("stroke", domainycolor); + // + var domainxwidth = $("#domainxwidth").val(); + $(".nv-x .nv-axis g path.domain").css("stroke-width", domainxwidth); + // + var domainywidth = $("#domainywidth").val(); + $(".nv-y .nv-axis g path.domain").css("stroke-width", domainywidth); + // + var clinecolor = $("#clinecolor").val(); + $("line.nv-regLine").css("stroke", clinecolor); + // + var clinewidth = $("#clinewidth").val(); + $("line.nv-regLine").css("stroke-width", clinewidth); +} + +function srchartupdatewh() { + // + var width = $("#srwidth").val(); + $("#srscatterplot2 svg").css("width", width); + // + var height = $("#srheight").val(); + $("#srscatterplot2 svg").css("height", height); + // + window.dispatchEvent(new Event('resize')); +} + +function srchartupdatedata() { + // + var size = $("#srmarksize").val(); + var shape = $("#srmarkshape").val(); + // + d3.select('#srscatterplot2 svg').datum(nv.log(srgetdata(size, shape))).call(srchart); + nv.utils.windowResize(srchart.update); +} + +srdrawg(); +srchartupdate(); +srchartupdatewh(); +srchartupdatedata(); + +$(".srchartupdate").change(function () { + srchartupdate(); +}); + +$(".srchartupdatewh").change(function () { + srchartupdatewh(); +}); + +$(".srchartupdatedata").change(function () { + srchartupdatedata(); +}); diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index 47b83018..fc9925e7 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -17,12 +17,65 @@

    Correlation Scatterplot

    +
    + + {% if trait_1.dataset.type == "ProbeSet" %} + +
    + [{{trait_1.symbol}} on {{trait_1.location_repr}} Mb] + {{trait_1.description_display}} +
    + {% elif trait_1.dataset.type == "Publish" %} + +
    + PubMed: {{trait_1.pubmed_text}} + {{trait_1.description_display}} +
    + {% endif %} + +
    + + {% if trait_2.dataset.type == "ProbeSet" %} + +
    + [{{trait_2.symbol}} on {{trait_2.location_repr}} Mb] + {{trait_2.description_display}} +
    + {% elif trait_2.dataset.type == "Publish" %} + +
    + PubMed: {{trait_2.pubmed_text}} + {{trait_2.description_display}} +
    + {% endif %} + +
    + +
    + - - - @@ -38,6 +91,44 @@ + + + + + + + + + + + + + + + + + + + +
    Width pxAxis X Color Correlation Line Color
    Axis Y ColorAxis Y Font pxDomain Y ColorDomain Y Width pxCorrelation Line Width px
    + +
    + + + +
    +
    + +
    + + + + + + - - - - - - - - - - - - - - - - - - - + + + +
    Width pxMark Size Height pxAxis Y ColorAxis Y Font pxDomain Y ColorDomain Y Width pxCorrelation Line Width pxMark Shape + + + + + + + + + + +
    StatisticValue
    Number {{jsdata.num_overlap}}
    Slope {{'%0.3f' % jsdata.slope}}
    Intercept {{'%0.3f' % jsdata.intercept}}
    r value {{'%0.3f' % jsdata.r_value}}
    P value {{'%0.3e' % jsdata.p_value}}
    - {% if trait_2.dataset.type == "ProbeSet" %} - -
    - [{{trait_2.symbol}} on {{trait_2.location_repr}} Mb] - {{trait_2.description_display}} -
    - {% elif trait_2.dataset.type == "Publish" %} - -
    - PubMed: {{trait_2.pubmed_text}} - {{trait_2.description_display}} -
    - {% endif %} + + +
    + +
    + + + + + + + + + + + + + + + + + + +
    Width pxMark Size + +
    Height pxMark Shape + +
    + +
    +

    @@ -159,13 +247,19 @@
    Number {{jsdata.num_overlap}}
    Slope {{'%0.3f' % jsdata.slope}}
    Intercept {{'%0.3f' % jsdata.intercept}}
    R value {{'%0.3f' % jsdata.r_value}}
    P value {{'%0.3e' % jsdata.p_value}}
    Slope {{'%0.3f' % jsdata.srslope}}
    Intercept {{'%0.3f' % jsdata.srintercept}}
    r value {{'%0.3f' % jsdata.srr_value}}
    P value {{'%0.3e' % jsdata.srp_value}}
    +
    + +
    + +
    + {% endblock %} {% block js %} @@ -179,4 +273,5 @@ + {% endblock %} -- cgit v1.2.3 From cfe7dee2903bde6b497559e3bef4615a690819c6 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 29 Aug 2017 16:15:46 +0000 Subject: Mostly changes related to getting gemma working with covariates and BIMBAM file format Other changes include: - Fixing links in the network graph - Changing button colors on show trait page - Changing color scheme for heatmap - Making rows highlight in yellow when clicked on - Some changes to table appearance (like giving gene global search a horizontal scroll) --- wqflask/base/webqtlConfig.py | 4 +- wqflask/wqflask/marker_regression/gemma_mapping.py | 151 +++++++++++++++++---- .../wqflask/marker_regression/marker_regression.py | 5 +- .../marker_regression/marker_regression_gn1.py | 19 ++- wqflask/wqflask/network_graph/network_graph.py | 12 +- wqflask/wqflask/show_trait/show_trait.py | 6 +- .../javascript/get_covariates_from_collection.js | 106 ++------------- .../wqflask/static/new/javascript/lodheatmap.js | 2 +- .../wqflask/static/new/javascript/network_graph.js | 4 +- .../wqflask/static/new/javascript/show_trait.js | 23 ++-- .../new/javascript/show_trait_mapping_tools.js | 15 ++ .../packages/DataTables/css/jquery.dataTables.css | 12 +- .../static/packages/bootstrap/css/bootstrap.css | 6 +- .../packages/bootstrap/css/non-responsive.css | 2 +- wqflask/wqflask/templates/collections/list.html | 5 - wqflask/wqflask/templates/gsearch_gene.html | 4 +- .../wqflask/templates/marker_regression_gn1.html | 1 + wqflask/wqflask/templates/search_result_page.html | 2 + wqflask/wqflask/templates/show_trait.html | 1 + .../show_trait_calculate_correlations.html | 2 +- .../templates/show_trait_mapping_tools.html | 62 +++++++-- wqflask/wqflask/views.py | 2 + 22 files changed, 263 insertions(+), 183 deletions(-) diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py index e5f10edf..c3f1e76a 100644 --- a/wqflask/base/webqtlConfig.py +++ b/wqflask/base/webqtlConfig.py @@ -70,8 +70,8 @@ assert_writable_dir(TMPDIR) CACHEDIR = mk_dir(TMPDIR+'/cache/') # We can no longer write into the git tree: -GENERATED_IMAGE_DIR = mk_dir(TMPDIR+'/generated/') -GENERATED_TEXT_DIR = mk_dir(TMPDIR+'/generated_text/') +GENERATED_IMAGE_DIR = mk_dir(TMPDIR+'generated/') +GENERATED_TEXT_DIR = mk_dir(TMPDIR+'generated_text/') # Make sure we have permissions to access these assert_writable_dir(CACHEDIR) diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 6e2cb972..31e94266 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -1,24 +1,75 @@ import os, math from base import webqtlConfig +from base.trait import GeneralTrait +from base.data_set import create_dataset from utility.tools import flat_files, GEMMA_COMMAND -def run_gemma(this_dataset, samples, vals): +import utility.logger +logger = utility.logger.getLogger(__name__ ) + +def run_gemma(this_dataset, samples, vals, covariates, method): """Generates p-values for each marker using GEMMA""" print("INSIDE GEMMA_MAPPING") - gen_pheno_txt_file(this_dataset, vals) + gen_pheno_txt_file(this_dataset, vals, method) + + if not os.path.isfile("{}{}_output.assoc.txt".format(webqtlConfig.GENERATED_IMAGE_DIR, this_dataset.group.name)): + open("{}{}_output.assoc.txt".format(webqtlConfig.GENERATED_IMAGE_DIR, this_dataset.group.name), "w+") - # use GEMMA_RUN in the next one, create a unique temp file + logger.debug("COVARIATES_GEMMA:", covariates) - gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -outdir %s -o %s_output' % (flat_files('mapping'), - this_dataset.group.name, - flat_files('mapping'), - this_dataset.group.name, - webqtlConfig.GENERATED_IMAGE_DIR, - this_dataset.group.name) - print("gemma_command:" + gemma_command) + if covariates != "": + gen_covariates_file(this_dataset, covariates) + if method == "gemma": + #gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -c %s/%s_covariates.txt -o %s_output' % (flat_files('mapping'), + gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.cXX.txt -lmm 1 -maf 0.1 -c %s/%s_covariates.txt -outdir %s -o %s_output' % (flat_files('mapping'), + this_dataset.group.name, + flat_files('mapping'), + this_dataset.group.name, + flat_files('mapping'), + this_dataset.group.name, + webqtlConfig.GENERATED_IMAGE_DIR, + this_dataset.group.name) + # use GEMMA_RUN in the next one, create a unique temp file + else: + logger.debug("FLAT FILES:", flat_files('mapping')) + #gemma_command = GEMMA_COMMAND + ' -g %s/%s_geno.txt -p %s/%s_pheno.txt -a %s/%s_snps.txt -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -c %s/%s_covariates.txt -o %s_output' % (flat_files('genotype/bimbam'), + gemma_command = GEMMA_COMMAND + ' -g %s/%s_geno.txt -p %s/%s_pheno.txt -a %s/%s_snps.txt -k %s/%s.cXX.txt -lmm 1 -maf 0.1 -c %s/%s_covariates.txt -outdir %s -debug -o %s_output' % (flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('mapping'), + this_dataset.group.name, + webqtlConfig.GENERATED_IMAGE_DIR, + this_dataset.group.name) + else: + if method == "gemma": + #gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -o %s_output' % (flat_files('mapping'), + gemma_command = GEMMA_COMMAND + ' -bfile %s/%s -k %s/%s.cXX.txt -lmm 1 -maf 0.1 -outdir %s -o %s_output' % (flat_files('mapping'), + this_dataset.group.name, + flat_files('mapping'), + this_dataset.group.name, + webqtlConfig.GENERATED_IMAGE_DIR, + this_dataset.group.name) + else: + #gemma_command = GEMMA_COMMAND + ' -g %s/%s_geno.txt -p %s/%s_pheno.txt -a %s/%s_snps.txt -k %s/%s.sXX.txt -lmm 1 -maf 0.1 -o %s_output' % (flat_files('genotype/bimbam'), + gemma_command = GEMMA_COMMAND + ' -g %s/%s_geno.txt -p %s/%s_pheno.txt -a %s/%s_snps.txt -k %s/%s.cXX.txt -lmm 1 -maf 0.1 -outdir %s -debug -o %s_output' % (flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + flat_files('genotype/bimbam'), + this_dataset.group.name, + webqtlConfig.GENERATED_IMAGE_DIR, + this_dataset.group.name) + logger.debug("gemma_command:" + gemma_command) os.system(gemma_command) @@ -26,27 +77,70 @@ def run_gemma(this_dataset, samples, vals): return marker_obs -def gen_pheno_txt_file(this_dataset, vals): +def gen_pheno_txt_file(this_dataset, vals, method): """Generates phenotype file for GEMMA""" - current_file_data = [] - with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "r") as outfile: - for i, line in enumerate(outfile): - split_line = line.split() - current_file_data.append(split_line) - - with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "w") as outfile: - for i, line in enumerate(current_file_data): - if vals[i] == "x": - this_val = -9 + if method == "gemma": + current_file_data = [] + with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "r") as outfile: + for i, line in enumerate(outfile): + split_line = line.split() + current_file_data.append(split_line) + + with open("{}/{}.fam".format(flat_files('mapping'), this_dataset.group.name), "w") as outfile: + for i, line in enumerate(current_file_data): + if vals[i] == "x": + this_val = -9 + else: + this_val = vals[i] + outfile.write("0" + " " + line[1] + " " + line[2] + " " + line[3] + " " + line[4] + " " + str(this_val) + "\n") + else: + current_file_data = [] + with open("{}/{}_pheno.txt".format(flat_files('genotype/bimbam'), this_dataset.group.name), "w") as outfile: + for value in vals: + if value == "x": + outfile.write("NA\n") + else: + outfile.write(value + "\n") + +def gen_covariates_file(this_dataset, covariates): + covariate_list = covariates.split(",") + covariate_data_object = [] + for covariate in covariate_list: + this_covariate_data = [] + trait_name = covariate.split(":")[0] + dataset_ob = create_dataset(covariate.split(":")[1]) + trait_ob = GeneralTrait(dataset=dataset_ob, + name=trait_name, + cellid=None) + + #trait_samples = this_dataset.group.all_samples_ordered() + this_dataset.group.get_samplelist() + trait_samples = this_dataset.group.samplelist + logger.debug("SAMPLES:", trait_samples) + trait_sample_data = trait_ob.data + logger.debug("SAMPLE DATA:", trait_sample_data) + for index, sample in enumerate(trait_samples): + if sample in trait_sample_data: + sample_value = trait_sample_data[sample].value + this_covariate_data.append(sample_value) else: - this_val = vals[i] - outfile.write("0" + " " + line[1] + " " + line[2] + " " + line[3] + " " + line[4] + " " + str(this_val) + "\n") + this_covariate_data.append("-9") + covariate_data_object.append(this_covariate_data) + + with open("{}/{}_covariates.txt".format(flat_files('mapping'), this_dataset.group.name), "w") as outfile: + for i in range(len(covariate_data_object[0])): + for this_covariate in covariate_data_object: + outfile.write(str(this_covariate[i]) + "\t") + outfile.write("\n") def parse_gemma_output(this_dataset): included_markers = [] p_values = [] marker_obs = [] + previous_chr = 0 + + #with open("/home/zas1024/gene/wqflask/output/{}_output.assoc.txt".format(this_dataset.group.name)) as output_file: with open("{}{}_output.assoc.txt".format(webqtlConfig.GENERATED_IMAGE_DIR, this_dataset.group.name)) as output_file: for line in output_file: if line.startswith("chr"): @@ -54,7 +148,16 @@ def parse_gemma_output(this_dataset): else: marker = {} marker['name'] = line.split("\t")[1] - marker['chr'] = int(line.split("\t")[0]) + if line.split("\t")[0] != "X" and line.split("\t")[0] != "X/Y": + marker['chr'] = int(line.split("\t")[0]) + else: + marker['chr'] = line.split("\t")[0] + # try: + # marker['chr'] = int(line.split("\t")[0]) + # except: + # marker['chr'] = previous_chr + 1 + # if marker['chr'] != previous_chr: + # previous_chr = marker['chr'] marker['Mb'] = float(line.split("\t")[2]) / 1000000 marker['p_value'] = float(line.split("\t")[10]) if math.isnan(marker['p_value']) or (marker['p_value'] <= 0): diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index 60424468..55bbacac 100644 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -92,6 +92,7 @@ class MarkerRegression(object): self.num_perm = 0 self.perm_output = [] self.bootstrap_results = [] + self.covariates = start_vars['covariates'] #ZS: This is passed to GN1 code for single chr mapping self.selected_chr = -1 @@ -153,11 +154,11 @@ class MarkerRegression(object): self.genofile_string = start_vars['genofile'] self.dataset.group.genofile = self.genofile_string.split(":")[0] self.dataset.group.get_markers() - if self.mapping_method == "gemma": + if self.mapping_method == "gemma" or self.mapping_method == "gemma_bimbam": self.score_type = "-log(p)" self.manhattan_plot = True with Bench("Running GEMMA"): - marker_obs = gemma_mapping.run_gemma(self.dataset, self.samples, self.vals) + marker_obs = gemma_mapping.run_gemma(self.dataset, self.samples, self.vals, self.covariates, self.mapping_method) results = marker_obs elif self.mapping_method == "rqtl_plink": results = self.run_rqtl_plink() diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/marker_regression_gn1.py index 08332e7d..93d75a03 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/marker_regression_gn1.py @@ -255,6 +255,8 @@ class MarkerRegression(object): self.controlLocus = start_vars['control_marker'] else: self.controlLocus = "" + if 'covariates' in start_vars.keys(): + self.covariates = start_vars['covariates'] #try: self.selectedChr = int(start_vars['selected_chr']) @@ -1369,7 +1371,10 @@ class MarkerRegression(object): #draw gray blocks for 3' and 5' UTR blocks if cdsStart and cdsEnd: - + logger.debug("txStart:", txStart) + logger.debug("cdsStart:", cdsStart) + logger.debug("txEnd:", txEnd) + logger.debug("cdsEnd:", cdsEnd) utrStartPix = (txStart-startMb)*plotXScale + xLeftOffset utrEndPix = (cdsStart-startMb)*plotXScale + xLeftOffset if (utrStartPix < xLeftOffset): @@ -1380,9 +1385,10 @@ class MarkerRegression(object): utrEndPix = xLeftOffset + plotWidth if (utrStartPix > xLeftOffset + plotWidth): utrStartPix = xLeftOffset + plotWidth - canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) + #canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) - if self.DRAW_UTR_LABELS and self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: + #if self.DRAW_UTR_LABELS and self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: + if self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: if strand == "-": labelText = "3'" else: @@ -1401,10 +1407,11 @@ class MarkerRegression(object): utrEndPix = xLeftOffset + plotWidth if (utrStartPix > xLeftOffset + plotWidth): utrStartPix = xLeftOffset + plotWidth - canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) + #canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) - if self.DRAW_UTR_LABELS and self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: - if tstrand == "-": + #if self.DRAW_UTR_LABELS and self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: + if self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: + if strand == "-": labelText = "5'" else: labelText = "3'" diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index 7eb5be61..b42904a4 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -182,24 +182,18 @@ class NetworkGraph(object): self.edges_list.append(edge_dict) if trait_db[1].type == "ProbeSet": - node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), - 'name' : str(this_trait.name), - 'dataset' : str(this_trait.dataset.name), + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), 'label' : this_trait.symbol, 'symbol' : this_trait.symbol, 'geneid' : this_trait.geneid, 'omim' : this_trait.omim, 'max_corr' : max_corr } } elif trait_db[1].type == "Publish": - node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), - 'name' : str(this_trait.name), - 'dataset' : str(this_trait.dataset.name), + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), 'label' : this_trait.name, 'max_corr' : max_corr } } else: - node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), - 'name' : str(this_trait.name), - 'dataset' : str(this_trait.dataset.name), + node_dict = { 'data' : {'id' : str(this_trait.name) + ":" + str(this_trait.dataset.name), 'label' : this_trait.name, 'max_corr' : max_corr } } self.nodes_list.append(node_dict) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index b2dfc4ac..13ad4a8f 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -133,9 +133,9 @@ class ShowTrait(object): self.sample_group_types = OrderedDict() if len(self.sample_groups) > 1: - self.sample_group_types['samples_primary'] = self.dataset.group.name + " Only" - self.sample_group_types['samples_other'] = "Non-" + self.dataset.group.name - self.sample_group_types['samples_all'] = "All Cases" + self.sample_group_types['samples_primary'] = self.dataset.group.name + self.sample_group_types['samples_other'] = "Other" + self.sample_group_types['samples_all'] = "All" else: self.sample_group_types['samples_primary'] = self.dataset.group.name sample_lists = [group.sample_list for group in self.sample_groups] diff --git a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js index c267b045..92e2b13b 100644 --- a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js +++ b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js @@ -2,8 +2,6 @@ var add_trait_data, assemble_into_json, back_to_collections, collection_click, collection_list, color_by_trait, create_trait_data_csv, get_this_trait_vals, get_trait_data, process_traits, selected_traits, submit_click, this_trait_data, trait_click, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; -console.log("before get_traits_from_collection"); - collection_list = null; this_trait_data = null; @@ -25,109 +23,30 @@ collection_click = function() { }; submit_click = function() { - var all_vals, sample, samples, scatter_matrix, this_trait_vals, trait, trait_names, trait_vals_csv, traits, _i, _j, _len, _len1, _ref; - selected_traits = {}; - traits = []; + var covariates_string = ""; $('#collections_holder').find('input[type=checkbox]:checked').each(function() { - var this_dataset, this_trait, this_trait_url; + var this_dataset, this_trait; this_trait = $(this).parents('tr').find('.trait').text(); console.log("this_trait is:", this_trait); this_dataset = $(this).parents('tr').find('.dataset').text(); console.log("this_dataset is:", this_dataset); - this_trait_url = "/trait/get_sample_data?trait=" + this_trait + "&dataset=" + this_dataset; - return $.ajax({ - dataType: "json", - url: this_trait_url, - async: false, - success: add_trait_data - }); + covariates_string += this_trait + ":" + this_dataset + "," }); - console.log("SELECTED_TRAITS IS:", selected_traits); - trait_names = []; - samples = $('input[name=allsamples]').val().split(" "); - all_vals = []; - this_trait_vals = get_this_trait_vals(samples); - all_vals.push(this_trait_vals); - _ref = Object.keys(selected_traits); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - trait = _ref[_i]; - trait_names.push(trait); - this_trait_vals = []; - for (_j = 0, _len1 = samples.length; _j < _len1; _j++) { - sample = samples[_j]; - if (__indexOf.call(Object.keys(selected_traits[trait]), sample) >= 0) { - this_trait_vals.push(parseFloat(selected_traits[trait][sample])); - } else { - this_trait_vals.push(null); - } - } - all_vals.push(this_trait_vals); - } - trait_vals_csv = create_trait_data_csv(selected_traits); - scatter_matrix = new ScatterMatrix(trait_vals_csv); - scatter_matrix.render(); - return $.colorbox.close(); -}; + // Trim the last comma + covariates_string = covariates_string.substring(0, covariates_string.length - 1) + console.log("COVARIATES:", covariates_string) -create_trait_data_csv = function(selected_traits) { - var all_vals, index, sample, sample_vals, samples, this_trait_vals, trait, trait_names, trait_vals_csv, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref; - trait_names = []; - trait_names.push($('input[name=trait_id]').val()); - samples = $('input[name=allsamples]').val().split(" "); - all_vals = []; - this_trait_vals = get_this_trait_vals(samples); - all_vals.push(this_trait_vals); - _ref = Object.keys(selected_traits); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - trait = _ref[_i]; - trait_names.push(trait); - this_trait_vals = []; - for (_j = 0, _len1 = samples.length; _j < _len1; _j++) { - sample = samples[_j]; - if (__indexOf.call(Object.keys(selected_traits[trait]), sample) >= 0) { - this_trait_vals.push(parseFloat(selected_traits[trait][sample])); - } else { - this_trait_vals.push(null); - } - } - all_vals.push(this_trait_vals); - } - console.log("all_vals:", all_vals); - trait_vals_csv = trait_names.join(","); - trait_vals_csv += "\n"; - for (index = _k = 0, _len2 = samples.length; _k < _len2; index = ++_k) { - sample = samples[index]; - if (all_vals[0][index] === null) { - continue; - } - sample_vals = []; - for (_l = 0, _len3 = all_vals.length; _l < _len3; _l++) { - trait = all_vals[_l]; - sample_vals.push(trait[index]); - } - trait_vals_csv += sample_vals.join(","); - trait_vals_csv += "\n"; - } - return trait_vals_csv; + $("input[name=covariates]").val(covariates_string) + + return $.colorbox.close(); }; trait_click = function() { var dataset, this_trait_url, trait; - console.log("Clicking on:", $(this)); trait = $(this).parent().find('.trait').text(); dataset = $(this).parent().find('.dataset').text(); - console.log("BEFORE COVAR:", trait + ":" + dataset) - $('input[name=covariates]').val(trait + ":" + dataset) - console.log("AFTER COVAR:", $('input[name=covariates]').val()) + $("input[name=covariates]").val(trait + ":" + dataset) return $.colorbox.close(); - // this_trait_url = "/trait/get_sample_data?trait=" + trait + "&dataset=" + dataset; - // console.log("this_trait_url", this_trait_url); - // $.ajax({ - // dataType: "json", - // url: this_trait_url, - // success: get_trait_data - // }); - // return $.colorbox.close(); }; add_trait_data = function(trait_data, textStatus, jqXHR) { @@ -140,9 +59,7 @@ add_trait_data = function(trait_data, textStatus, jqXHR) { get_trait_data = function(trait_data, textStatus, jqXHR) { var sample, samples, this_trait_vals, trait_sample_data, vals, _i, _len; - console.log("trait:", trait_data[0]); trait_sample_data = trait_data[1]; - console.log("trait_sample_data:", trait_sample_data); samples = $('input[name=allsamples]').val().split(" "); vals = []; for (_i = 0, _len = samples.length; _i < _len; _i++) { @@ -158,7 +75,6 @@ get_trait_data = function(trait_data, textStatus, jqXHR) { } $('#hidden_inputs').append(''); this_trait_vals = get_this_trait_vals(samples); - console.log("THE LENGTH IS:", $('input[name=vals]').length); return color_by_trait(trait_sample_data); }; @@ -174,7 +90,6 @@ get_this_trait_vals = function(samples) { this_trait_vals.push(null); } } - console.log("this_trait_vals:", this_trait_vals); this_vals_json = '[' + this_trait_vals.toString() + ']'; return this_trait_vals; }; @@ -231,7 +146,6 @@ back_to_collections = function() { return $('#collections_holder').colorbox.resize(); }; -console.log("inside get_traits_from_collection"); $(".collection_line").on("click", collection_click); $("#submit").on("click", submit_click); $(".trait").on("click", trait_click); diff --git a/wqflask/wqflask/static/new/javascript/lodheatmap.js b/wqflask/wqflask/static/new/javascript/lodheatmap.js index f604cd10..965a1d53 100644 --- a/wqflask/wqflask/static/new/javascript/lodheatmap.js +++ b/wqflask/wqflask/static/new/javascript/lodheatmap.js @@ -20,7 +20,7 @@ lodheatmap = function() { chrGap = 8; titlepos = 20; rectcolor = d3.rgb(230, 230, 230); - colors = ["blue", "white", "crimson"]; + colors = ["slateblue", "white", "red"]; title = ""; xlab = "Chromosome"; ylab = ""; diff --git a/wqflask/wqflask/static/new/javascript/network_graph.js b/wqflask/wqflask/static/new/javascript/network_graph.js index 03ef1c98..0129bcae 100644 --- a/wqflask/wqflask/static/new/javascript/network_graph.js +++ b/wqflask/wqflask/static/new/javascript/network_graph.js @@ -6,7 +6,7 @@ window.onload=function() { container: $('#cytoscapeweb'), // container to render in elements: elements_list, - + style: [ // the stylesheet for the graph { selector: 'node', @@ -82,7 +82,7 @@ window.onload=function() { cy.nodes().qtip({ content: function(){ qtip_content = '' - gn_link = ''+''+this.data().id +''+'
    ' + gn_link = ''+''+this.data().id +''+'
    ' qtip_content += gn_link if (typeof(this.data().geneid) !== 'undefined'){ ncbi_link = 'NCBI'+'
    ' diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index f232c6eb..f08965e9 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -74,11 +74,14 @@ return open_trait_selection(); }; })(this)); - d3.select("#select_covariate").on("click", (function(_this) { + d3.select("#select_covariates").on("click", (function(_this) { return function() { return open_covariate_selection(); }; })(this)); + $("#remove_covariates").click(function () { + $("input[name=covariates]").val("") + }); d3.select("#clear_compare_trait").on("click", (function(_this) { return function() { return $('.scatter-matrix-container').remove(); @@ -101,15 +104,15 @@ })(this)); }; open_covariate_selection = function() { - return $('#collections_holder').load('/collections/list?select_covariates #collections_list', (function(_this) { + return $('#collections_holder').load('/collections/list #collections_list', (function(_this) { return function() { $.colorbox({ inline: true, href: "#collections_holder", onComplete: function(){ - console.log("before get script") + console.log("before get cov script") $.getScript("/static/new/javascript/get_covariates_from_collection.js"); - console.log("after get script") + console.log("after get cov script") } }); return $('a.collection_name').attr('onClick', 'return false'); @@ -199,16 +202,16 @@ }; make_table = function() { var header, key, row, row_line, table, the_id, the_rows, value, _i, _len, _ref, _ref1; - header = "Statistic"; + header = "Statistic"; _ref = js_data.sample_group_types; for (key in _ref) { if (!__hasProp.call(_ref, key)) continue; value = _ref[key]; the_id = process_id("column", key); if (Object.keys(_ref).length > 1) { - header += "" + value + ""; + header += "" + value + ""; } else { - header += "Value"; + header += "Value"; } } @@ -221,16 +224,16 @@ } row_line = ""; if (row.url != null) { - row_line += "
    " + row.pretty + ""; + row_line += "" + row.pretty + ""; } else { - row_line += "" + row.pretty + ""; + row_line += "" + row.pretty + ""; } _ref1 = js_data.sample_group_types; for (key in _ref1) { if (!__hasProp.call(_ref1, key)) continue; value = _ref1[key]; the_id = process_id(key, row.vn); - row_line += "foo"; + row_line += "foo"; } row_line += ""; the_rows += row_line; 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 d6cd8134..e11aaf4a 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -237,6 +237,21 @@ }; })(this)); + $("#gemma_bimbam_compute").on("click", (function(_this) { + return function() { + var form_data, url; + console.log("RUNNING GEMMA"); + //$("#static_progress_bar_container").modal(); + url = "/loading"; + $('input[name=method]').val("gemma_bimbam"); + $('input[name=maf]').val($('input[name=maf_gemma]').val()); + form_data = $('#trait_data_form').serialize(); + console.log("form_data is:", form_data); + return submit_special(url); + //return do_ajax_post(url, form_data); + }; + })(this)); + $("#interval_mapping_compute").on("click", (function(_this) { return function() { var form_data, url; diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css index a5b9f09c..f376d15e 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css @@ -80,7 +80,7 @@ table.dataTable tbody tr { background-color: #ffffff; } table.dataTable tbody tr.selected { - background-color: #abb9d3; + background-color: #ffee99; } table.dataTable tbody th, table.dataTable tbody td { @@ -111,13 +111,13 @@ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { background-color: #f9f9f9; } table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { - background-color: #abb9d3; + background-color: #FFEE99; } table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { background-color: whitesmoke; } table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected { - background-color: #a9b7d1; + background-color: #FFEE99; } table.dataTable.order-column tbody tr > .sorting_1, table.dataTable.order-column tbody tr > .sorting_2, @@ -143,7 +143,7 @@ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column. background-color: whitesmoke; } table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { - background-color: #a6b3cd; + background-color: #ffe047; } table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { background-color: #a7b5ce; @@ -161,7 +161,7 @@ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column background-color: #fdfdfd; } table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { - background-color: #acbad4; + background-color: #ffe047; } table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { background-color: #adbbd6; @@ -179,7 +179,7 @@ table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-colum background-color: #eeeeee; } table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { - background-color: #a1aec7; + background-color: #ffe047; } table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { background-color: #a2afc8; diff --git a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css index 91aaa98f..e6abe790 100644 --- a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css +++ b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css @@ -3803,7 +3803,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { color: #fff; - background-color: #428bca; + background-color: #3071a9; /* Tab cell background color */ } .nav-stacked > li { float: none; @@ -4485,7 +4485,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { z-index: 2; color: #fff; cursor: default; - background-color: #428bca; + background-color: #3071a9; border-color: #428bca; } .pagination > .disabled > span, @@ -4667,7 +4667,7 @@ a.badge:focus { } a.list-group-item.active > .badge, .nav-pills > .active > a > .badge { - color: #428bca; + color: #3071a9; background-color: #fff; } .nav-pills > li > a > .badge { diff --git a/wqflask/wqflask/static/packages/bootstrap/css/non-responsive.css b/wqflask/wqflask/static/packages/bootstrap/css/non-responsive.css index 9da73a8f..d352390f 100644 --- a/wqflask/wqflask/static/packages/bootstrap/css/non-responsive.css +++ b/wqflask/wqflask/static/packages/bootstrap/css/non-responsive.css @@ -97,7 +97,7 @@ body { .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff !important; - background-color: #428bca !important; + background-color: #3071a9 !important; } .navbar .navbar-nav .open .dropdown-menu > .disabled > a, .navbar .navbar-nav .open .dropdown-menu > .disabled > a:hover, diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html index cc60ecff..ad72052e 100644 --- a/wqflask/wqflask/templates/collections/list.html +++ b/wqflask/wqflask/templates/collections/list.html @@ -65,11 +65,6 @@ {% endfor %} - {% if "color_by_trait" in params %} - - {% else %} - - {% endif %}
    diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index c2f687fd..6f2ad0b8 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -27,8 +27,8 @@
    -
    - +
    +
    diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/marker_regression_gn1.html index 5afd134a..c6c6bc23 100644 --- a/wqflask/wqflask/templates/marker_regression_gn1.html +++ b/wqflask/wqflask/templates/marker_regression_gn1.html @@ -27,6 +27,7 @@ + diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 93e24cc7..9ad8a53e 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -234,6 +234,7 @@ "autoWidth": false, "deferRender": true, "bSortClasses": false, + "scrollX": true, "scrollY": "600px", "scrollCollapse": false, "scroller": true, @@ -306,6 +307,7 @@ "autoWidth": false, "deferRender": true, "bSortClasses": false, + "scrollY": "600px", "scrollCollapse": false, "scroller": false, "paging": false, diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 7c4dbc60..c2724fea 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -142,6 +142,7 @@ + diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index 0e15ce9c..c5f815ce 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -105,7 +105,7 @@
    -
    diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index bded60d2..1151c74b 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -15,6 +15,9 @@
  • R/qtl
  • +
  • + GEMMA +
  • {% endif %} {# if use_plink_gemma #} {% for mapping_method in dataset.group.mapping_names %} @@ -122,7 +125,7 @@
    -
    @@ -179,7 +182,7 @@ -->
    -
    @@ -286,30 +289,69 @@
    -
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    {% endif %} {# if use_plink_gemma #} {% if dataset.group.mapping_id == "2" or dataset.group.mapping_id == "4" %} -
    -
    +
    +
    - +
    +
    +
    + + +
    +
    +
    - -
    -
    @@ -329,7 +371,7 @@
    -
    diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 83496000..2d4fd0f2 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -514,6 +514,7 @@ def loading_page(): 'bootCheck', 'bootstrap_results', 'LRSCheck', + 'covariates', 'maf', 'manhattan_plot', 'control_marker', @@ -569,6 +570,7 @@ def marker_regression_page(): 'bootCheck', 'bootstrap_results', 'LRSCheck', + 'covariates', 'maf', 'manhattan_plot', 'control_marker', -- cgit v1.2.3 From 4f06516befcb16b802afcb81bae28b55279a3c1e Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Mon, 4 Sep 2017 02:15:11 -0500 Subject: gemma-wrapper: find binary in profile --- bin/genenetwork2 | 1 + etc/default_settings.py | 1 + wqflask/utility/tools.py | 12 ++++++++---- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 236d8f63..e07a4e32 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -78,6 +78,7 @@ else export PLINK_COMMAND="$GN2_PROFILE/bin/plink2" export PYLMM_COMMAND="$GN2_PROFILE/bin/pylmm_redis" export GEMMA_COMMAND="$GN2_PROFILE/bin/gemma" + export GEMMA_WRAPPER_COMMAND="$GN2_PROFILE/bin/gemma-wrapper" fi if [ -z $PYTHONPATH ] ; then echo "ERROR PYTHONPATH has not been set - use GN2_PROFILE!" diff --git a/etc/default_settings.py b/etc/default_settings.py index 1b609414..c00f6c8f 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -69,3 +69,4 @@ JS_GN_PATH = os.environ['HOME']+"/genenetwork/javascript" # PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read()) # PLINK_COMMAND = str.strip(os.popen("which plink2").read()) # GEMMA_COMMAND = str.strip(os.popen("which gemma").read()) +# GEMMA_WRAPPER_COMMAND = str.strip(os.popen("which gemma-wrapper").read()) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 867bc5c8..c5685cdd 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -113,6 +113,9 @@ def pylmm_command(guess=None): def gemma_command(guess=None): return assert_bin(get_setting("GEMMA_COMMAND",guess)) +def gemma_wrapper_command(guess=None): + return assert_bin(get_setting("GEMMA_WRAPPER_COMMAND",guess)) + def plink_command(guess=None): return assert_bin(get_setting("PLINK_COMMAND",guess)) @@ -240,10 +243,11 @@ JS_GUIX_PATH = get_setting('JS_GUIX_PATH') JS_GN_PATH = get_setting('JS_GN_PATH') # assert_dir(JS_GN_PATH) -PYLMM_COMMAND = pylmm_command() -GEMMA_COMMAND = gemma_command() -PLINK_COMMAND = plink_command() -TEMPDIR = tempdir() # defaults to UNIX TMPDIR +PYLMM_COMMAND = pylmm_command() +GEMMA_COMMAND = gemma_command() +GEMMA_WRAPPER_COMMAND = gemma_wrapper_command() +PLINK_COMMAND = plink_command() +TEMPDIR = tempdir() # defaults to UNIX TMPDIR # ---- Handle specific JS modules JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("Twitter-Post-Fetcher")) -- cgit v1.2.3 From 03e2facd6279f5413667dfcca4b2d223a54e4f4e Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 5 Sep 2017 16:48:55 +0000 Subject: Added file converting genofiles to bimbam --- wqflask/maintenance/convert_geno_to_bimbam.py | 239 ++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 wqflask/maintenance/convert_geno_to_bimbam.py diff --git a/wqflask/maintenance/convert_geno_to_bimbam.py b/wqflask/maintenance/convert_geno_to_bimbam.py new file mode 100644 index 00000000..05006d5c --- /dev/null +++ b/wqflask/maintenance/convert_geno_to_bimbam.py @@ -0,0 +1,239 @@ +#!/usr/bin/python + +""" +Convert .geno files to json + +This file goes through all of the genofiles in the genofile directory (.geno) +and converts them to json files that are used when running the marker regression +code + +""" + +from __future__ import print_function, division, absolute_import +import sys +sys.path.append("..") +import os +import glob +import traceback +import gzip + +#import numpy as np +#from pyLMM import lmm + +import simplejson as json + +from pprint import pformat as pf + +class EmptyConfigurations(Exception): pass + + + +class Marker(object): + def __init__(self): + self.name = None + self.chr = None + self.cM = None + self.Mb = None + self.genotypes = [] + +class ConvertGenoFile(object): + + def __init__(self, input_file, output_files): + + self.input_file = input_file + self.output_files = output_files + + self.mb_exists = False + self.cm_exists = False + self.markers = [] + + self.latest_row_pos = None + self.latest_col_pos = None + + self.latest_row_value = None + self.latest_col_value = None + + def convert(self): + + self.haplotype_notation = { + '@mat': "1", + '@pat': "0", + '@het': "0.5", + '@unk': "NA" + } + + self.configurations = {} + #self.skipped_cols = 3 + + #if self.input_file.endswith(".geno.gz"): + # print("self.input_file: ", self.input_file) + # self.input_fh = gzip.open(self.input_file) + #else: + self.input_fh = open(self.input_file) + + with open(self.output_files[0], "w") as self.geno_fh: + #if self.file_type == "geno": + self.process_csv() + #elif self.file_type == "snps": + # self.process_snps_file() + + + def process_csv(self): + for row_count, row in enumerate(self.process_rows()): + row_items = row.split("\t") + + this_marker = Marker() + this_marker.name = row_items[1] + this_marker.chr = row_items[0] + if self.cm_exists and self.mb_exists: + this_marker.cM = row_items[2] + this_marker.Mb = row_items[3] + genotypes = row_items[4:] + elif self.cm_exists: + this_marker.cM = row_items[2] + genotypes = row_items[3:] + elif self.mb_exists: + this_marker.Mb = row_items[2] + genotypes = row_items[3:] + else: + genotypes = row_items[2:] + for item_count, genotype in enumerate(genotypes): + if genotype.upper().strip() in self.configurations: + this_marker.genotypes.append(self.configurations[genotype.upper().strip()]) + else: + this_marker.genotypes.append("NA") + + #print("this_marker is:", pf(this_marker.__dict__)) + #if this_marker.chr == "14": + self.markers.append(this_marker.__dict__) + + self.write_to_bimbam() + + # with open(self.output_file, 'w') as fh: + # json.dump(self.markers, fh, indent=" ", sort_keys=True) + + # print('configurations:', str(configurations)) + #self.latest_col_pos = item_count + self.skipped_cols + #self.latest_col_value = item + + #if item_count != 0: + # self.output_fh.write(" ") + #self.output_fh.write(self.configurations[item.upper()]) + + #self.output_fh.write("\n") + + def write_to_bimbam(self): + with open(self.output_files[0], "w") as geno_fh: + # geno_fh.write(str(len(self.sample_list)) + "\n") + # geno_fh.write("2\n") + # geno_fh.write("IND") + # for sample in self.sample_list: + # geno_fh.write(" " + sample) + # geno_fh.write("\n") + for marker in self.markers: + geno_fh.write(marker['name']) + geno_fh.write(", X, Y") + geno_fh.write(", " + ", ".join(marker['genotypes'])) + geno_fh.write("\n") + + #pheno_fh = open(self.output_files[1], 'w') + with open(self.output_files[1], "w") as pheno_fh: + for sample in self.sample_list: + pheno_fh.write("1\n") + + with open(self.output_files[2], "w") as snp_fh: + for marker in self.markers: + if self.mb_exists: + snp_fh.write(marker['name'] +", " + str(int(float(marker['Mb'])*1000000)) + ", " + marker['chr'] + "\n") + else: + snp_fh.write(marker['name'] +", " + str(int(float(marker['cM'])*1000000)) + ", " + marker['chr'] + "\n") + + + def get_sample_list(self, row_contents): + self.sample_list = [] + if self.mb_exists: + if self.cm_exists: + self.sample_list = row_contents[4:] + else: + self.sample_list = row_contents[3:] + else: + if self.cm_exists: + self.sample_list = row_contents[3:] + else: + self.sample_list = row_contents[2:] + + def process_rows(self): + for self.latest_row_pos, row in enumerate(self.input_fh): + #if self.input_file.endswith(".geno.gz"): + # print("row: ", row) + self.latest_row_value = row + # Take care of headers + if not row.strip(): + continue + if row.startswith('#'): + continue + if row.startswith('Chr'): + if 'Mb' in row.split(): + self.mb_exists = True + if 'cM' in row.split(): + self.cm_exists = True + self.get_sample_list(row.split()) + continue + if row.startswith('@'): + key, _separater, value = row.partition(':') + key = key.strip() + value = value.strip() + if key in self.haplotype_notation: + self.configurations[value] = self.haplotype_notation[key] + continue + if not len(self.configurations): + raise EmptyConfigurations + yield row + + @classmethod + def process_all(cls, old_directory, new_directory): + os.chdir(old_directory) + for input_file in glob.glob("*"): + if not input_file.endswith(('geno', '.geno.gz')): + continue + group_name = ".".join(input_file.split('.')[:-1]) + geno_output_file = os.path.join(new_directory, group_name + "_geno.txt") + pheno_output_file = os.path.join(new_directory, group_name + "_pheno.txt") + snp_output_file = os.path.join(new_directory, group_name + "_snps.txt") + output_files = [geno_output_file, pheno_output_file, snp_output_file] + print("%s -> %s" % ( + os.path.join(old_directory, input_file), geno_output_file)) + convertob = ConvertGenoFile(input_file, output_files) + try: + convertob.convert() + except EmptyConfigurations as why: + print(" No config info? Continuing...") + #excepted = True + continue + except Exception as why: + + print(" Exception:", why) + print(traceback.print_exc()) + print(" Found in row %s at tabular column %s" % (convertob.latest_row_pos, + convertob.latest_col_pos)) + print(" Column is:", convertob.latest_col_value) + print(" Row is:", convertob.latest_row_value) + break + + #def process_snps_file(cls, snps_file, new_directory): + # output_file = os.path.join(new_directory, "mouse_families.json") + # print("%s -> %s" % (snps_file, output_file)) + # convertob = ConvertGenoFile(input_file, output_file) + + +if __name__=="__main__": + Old_Geno_Directory = """/home/zas1024/genotype_files/genotype/""" + New_Geno_Directory = """/home/zas1024/genotype_files/genotype/bimbam/""" + #Input_File = """/home/zas1024/gene/genotype_files/genotypes/BXD.geno""" + #Output_File = """/home/zas1024/gene/wqflask/wqflask/pylmm/data/bxd.snps""" + #convertob = ConvertGenoFile("/home/zas1024/gene/genotype_files/genotypes/SRxSHRSPF2.geno", "/home/zas1024/gene/genotype_files/new_genotypes/SRxSHRSPF2.json") + #convertob.convert() + ConvertGenoFile.process_all(Old_Geno_Directory, New_Geno_Directory) + #ConvertGenoFiles(Geno_Directory) + + #process_csv(Input_File, Output_File) \ No newline at end of file -- cgit v1.2.3 From 425f0e9d8977f8cf741f596315a56c91b750988a Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 7 Sep 2017 16:13:42 +0000 Subject: Added the script to convert bimbam to kinship matrices --- .../maintenance/generate_kinship_from_bimbam.py | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 wqflask/maintenance/generate_kinship_from_bimbam.py diff --git a/wqflask/maintenance/generate_kinship_from_bimbam.py b/wqflask/maintenance/generate_kinship_from_bimbam.py new file mode 100644 index 00000000..f322341d --- /dev/null +++ b/wqflask/maintenance/generate_kinship_from_bimbam.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +""" +Generate relatedness matrix files for GEMMA from BIMBAM genotype/phenotype files + +This file goes through all of the BIMBAM files in the bimbam diretory +and uses GEMMA to generate their corresponding kinship/relatedness matrix file + +""" + +from __future__ import print_function, division, absolute_import +import sys +sys.path.append("..") +import os +import glob + +class GenerateKinshipMatrices(object): + def __init__(self, group_name, geno_file, pheno_file): + self.group_name = group_name + self.geno_file = geno_file + self.pheno_file = pheno_file + + def generate_kinship(self): + gemma_command = "/gnu/store/xhzgjr0jvakxv6h3blj8z496xjig69b0-profile/bin/gemma -g " + self.geno_file + " -p " + self.pheno_file + " -gk 1 -outdir /home/zas1024/genotype_files/genotype/bimbam/ -o " + self.group_name + print("command:", gemma_command) + os.system(gemma_command) + + @classmethod + def process_all(self, geno_dir, bimbam_dir): + os.chdir(geno_dir) + for input_file in glob.glob("*"): + if not input_file.endswith(('geno', '.geno.gz')): + continue + group_name = ".".join(input_file.split('.')[:-1]) + geno_input_file = os.path.join(bimbam_dir, group_name + "_geno.txt") + pheno_input_file = os.path.join(bimbam_dir, group_name + "_pheno.txt") + convertob = GenerateKinshipMatrices(group_name, geno_input_file, pheno_input_file) + try: + convertob.generate_kinship() + except EmptyConfigurations as why: + print(" No config info? Continuing...") + continue + except Exception as why: + + print(" Exception:", why) + print(traceback.print_exc()) + print(" Found in row %s at tabular column %s" % (convertob.latest_row_pos, + convertob.latest_col_pos)) + print(" Column is:", convertob.latest_col_value) + print(" Row is:", convertob.latest_row_value) + break + + +if __name__=="__main__": + Geno_Directory = """/home/zas1024/genotype_files/genotype/""" + Bimbam_Directory = """/home/zas1024/genotype_files/genotype/bimbam/""" + GenerateKinshipMatrices.process_all(Geno_Directory, Bimbam_Directory) + + #./gemma -g /home/zas1024/genotype_files/genotype/bimbam/BXD_geno.txt -p /home/zas1024/genotype_files/genotype/bimbam/BXD_pheno.txt -gk 1 -o BXD \ No newline at end of file -- cgit v1.2.3 From c0188f02830dace2fc82392788f987e3c46ee12a Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 7 Sep 2017 16:51:10 +0000 Subject: Updated show trait page to correctly show GEMMA options for certain data sets --- wqflask/wqflask/templates/show_trait_mapping_tools.html | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index 1151c74b..c24a5853 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -4,7 +4,6 @@
    {% endif %} - {# if use_plink_gemma #} - {% if dataset.group.mapping_id == "2" or dataset.group.mapping_id == "4" %} -
    + {% for mapping_method in dataset.group.mapping_names %} + {% if mapping_method == "GEMMA" %} + - {% if dataset.group.mapping_id == "4" %} + {% elif mapping_method == "PLINK" %}
    -- cgit v1.2.3 From 3adc1de4973bc5b92b88c7d8865ff1ec18e67965 Mon Sep 17 00:00:00 2001 From: Lei Yan Date: Tue, 12 Sep 2017 21:33:20 +0000 Subject: change corr_scatterplot precision format --- .../new/javascript/draw_corr_scatterplot-2.js | 6 ++++ wqflask/wqflask/templates/corr_scatterplot.html | 36 +++++++++++----------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js index 17f939cc..4a0f2c55 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot-2.js @@ -93,6 +93,12 @@ function chartupdate() { // var clinewidth = $("#clinewidth").val(); $("line.nv-regLine").css("stroke-width", clinewidth); + // + var axiscolor = $("#axiscolor").val(); + $(".tick").css("stroke", axiscolor); + // + var axiswidth = $("#axiswidth").val(); + $("line.nv-regLine").css("stroke-width", axiswidth); } function chartupdatewh() { diff --git a/wqflask/wqflask/templates/corr_scatterplot.html b/wqflask/wqflask/templates/corr_scatterplot.html index fc9925e7..227e1116 100644 --- a/wqflask/wqflask/templates/corr_scatterplot.html +++ b/wqflask/wqflask/templates/corr_scatterplot.html @@ -91,6 +91,9 @@
    + + + @@ -109,6 +112,9 @@ + + +
    Correlation Line Color Axis Line Color
    Correlation Line Width pxAxis Line Width px
    @@ -129,7 +135,10 @@ Width px - Mark Size + Height + px + + Size - - - - Height - px - - Mark Shape + Shape px - Mark Size + Height + px + + Size - - - - - Height - px - Mark Shape + Shape
    +
    + +
    + + +
    +
    -
    @@ -267,24 +271,55 @@ $(document).ready( function () { + var table_json = {{ json_results | safe }} + + + {% if target_dataset.type == "ProbeSet" %} + var json_array = new Array(); + + for (i=0; i < table_json.length; i++){ + json_array.push({ + checkbox: table_json[i]["checkbox"], + index: table_json[i]["index"], + trait_id: table_json[i]["trait_id"], + symbol: table_json[i]["symbol"], + description: table_json[i]["description"], + location: table_json[i]["location"], + mean: table_json[i]["mean"], + lrs_score: table_json[i]["lrs_score"], + lrs_location: table_json[i]["lrs_location"], + additive: table_json[i]["additive"], + sample_r: table_json[i]["sample_r"], + num_overlap: table_json[i]["num_overlap"], + sample_p: table_json[i]["sample_p"], + lit_corr: table_json[i]["lit_corr"], + tissue_corr: table_json[i]["tissue_corr"] + }); + console.log("JSON_DATA:", json_array); + } + //console.log("JSON_DATA:", json_array) + $("#trait_table").tabulator({ + data: json_array, columns:[ - {title:"Index", formatter:"html"}, - {title:"Record", formatter:"html"}, - {title:"Symbol", formatter:"plaintext"}, - {title:"Description", formatter:"textarea", width:"25%"}, - {title:"Location", formatter:"plaintext"}, - {title:"Mean", formatter:"plaintext"}, - {title:"Max LRS", formatter:"plaintext"}, - {title:"Max LRS Location", formatter:"plaintext"}, - {title:"Additive Effect", formatter:"plaintext"}, - {title:"Sample r", formatter:"html"}, - {title:"N", formatter:"plaintext"}, - {title:"Sample p(r)", formatter:"plaintext"}, - {title:"Lit r", formatter:"plaintext"}, - {title:"Tissue r", formatter:"plaintext"} + {title:"", field:"checkbox", formatter:"html"}, + {title:"Index", field:"index", formatter:"plaintext"}, + {title:"Record", field:"trait_id", formatter:"html"}, + {title:"Symbol", field:"symbol", formatter:"plaintext"}, + {title:"Description", field:"description", formatter:"textarea", width:"25%"}, + {title:"Location", field:"location", formatter:"plaintext"}, + {title:"Mean", field:"mean", formatter:"plaintext"}, + {title:"Max LRS", field:"lrs_score", formatter:"plaintext"}, + {title:"Max LRS Location", field:"lrs_location", formatter:"plaintext"}, + {title:"Additive Effect", field:"additive", formatter:"plaintext"}, + {title:"Sample r", field:"sample_r", formatter:"html"}, + {title:"N", field:"num_overlap", formatter:"plaintext"}, + {title:"Sample p(r)", field:"sample_p", formatter:"plaintext"}, + {title:"Lit r", field:"lit_corr", formatter:"plaintext"}, + {title:"Tissue r", field:"tissue_corr", formatter:"plaintext"} ] }); + {% endif %} $('#trait_table tr').click(function(event) { if (event.target.type !== 'checkbox') { diff --git a/wqflask/wqflask/templates/empty_collection.html b/wqflask/wqflask/templates/empty_collection.html index 3f2b3786..d1b779ef 100644 --- a/wqflask/wqflask/templates/empty_collection.html +++ b/wqflask/wqflask/templates/empty_collection.html @@ -6,7 +6,7 @@
    -

    You must select at least one trait to use the {{ tool }}.

    +

    You must select at least two traits to use the {{ tool }}.

    diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 4e81c29c..187b60dc 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -743,7 +743,7 @@ def corr_matrix_page(): start_vars = request.form traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] - if traits[0] != "": + if len(traits) > 1: template_vars = show_corr_matrix.CorrelationMatrix(start_vars) template_vars.js_data = json.dumps(template_vars.js_data, default=json_default_handler, -- cgit v1.2.3 From 51383c96dc275f4462716398f9ec665fbd84802a Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 2 Mar 2018 17:59:28 +0000 Subject: Added option to display selected covariates for GEMMA mapping Changed layout/appearance of mapping options Partially fixed issue with deleting collections Changes to correlation table still in progress; having trouble getting tabulator to load JSON --- wqflask/wqflask/collect.py | 7 +- wqflask/wqflask/marker_regression/gemma_mapping.py | 4 +- .../javascript/get_covariates_from_collection.js | 5 + .../wqflask/static/new/javascript/show_trait.js | 3 +- wqflask/wqflask/templates/collections/list.html | 12 +- wqflask/wqflask/templates/correlation_page.html | 43 +++-- .../templates/show_trait_mapping_tools.html | 208 ++++++++++----------- 7 files changed, 146 insertions(+), 136 deletions(-) diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 2f6c3a96..0f72b29d 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -349,8 +349,11 @@ def delete_collection(): db_session.delete(uc) db_session.commit() else: - collection_name = params['collection_name'] - user_manager.AnonUser().delete_collection(collection_name) + if "collection_name" in params: + collection_name = params['collection_name'] + else: + for this_collection in params['uc_id'].split(":"): + user_manager.AnonUser().delete_collection(this_collection) flash("We've deleted the collection: {}.".format(collection_name), "alert-info") diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 233a5c76..7563eb2c 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -235,7 +235,7 @@ def parse_loco_output(this_dataset, gwa_output_filename): else: marker['chr'] = line.split("\t")[0] marker['Mb'] = float(line.split("\t")[2]) / 1000000 - marker['p_value'] = float(line.split("\t")[10]) + marker['p_value'] = float(line.split("\t")[11]) if math.isnan(marker['p_value']) or (marker['p_value'] <= 0): marker['lod_score'] = 0 #marker['lrs_value'] = 0 @@ -245,6 +245,6 @@ def parse_loco_output(this_dataset, gwa_output_filename): marker_obs.append(marker) included_markers.append(line.split("\t")[1]) - p_values.append(float(line.split("\t")[10])) + p_values.append(float(line.split("\t")[11])) return marker_obs \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js index 92e2b13b..f2e694d8 100644 --- a/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js +++ b/wqflask/wqflask/static/new/javascript/get_covariates_from_collection.js @@ -24,6 +24,7 @@ collection_click = function() { submit_click = function() { var covariates_string = ""; + var covariates_display_string = ""; $('#collections_holder').find('input[type=checkbox]:checked').each(function() { var this_dataset, this_trait; this_trait = $(this).parents('tr').find('.trait').text(); @@ -31,12 +32,15 @@ submit_click = function() { this_dataset = $(this).parents('tr').find('.dataset').text(); console.log("this_dataset is:", this_dataset); covariates_string += this_trait + ":" + this_dataset + "," + covariates_display_string += this_trait + "\n" }); // Trim the last comma covariates_string = covariates_string.substring(0, covariates_string.length - 1) + //covariates_display_string = covariates_display_string.substring(0, covariates_display_string.length - 2) console.log("COVARIATES:", covariates_string) $("input[name=covariates]").val(covariates_string) + $(".selected_covariates").val(covariates_display_string) return $.colorbox.close(); }; @@ -46,6 +50,7 @@ trait_click = function() { trait = $(this).parent().find('.trait').text(); dataset = $(this).parent().find('.dataset').text(); $("input[name=covariates]").val(trait + ":" + dataset) + $(".selected_covariates").text(trait) return $.colorbox.close(); }; diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 099d8010..df10c060 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -88,7 +88,8 @@ }; })(this)); $("#remove_covariates").click(function () { - $("input[name=covariates]").val("") + $("input[name=covariates]").val("") + $(".selected_covariates").val("") }); d3.select("#clear_compare_trait").on("click", (function(_this) { return function() { diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html index ad72052e..e7f3229b 100644 --- a/wqflask/wqflask/templates/collections/list.html +++ b/wqflask/wqflask/templates/collections/list.html @@ -26,13 +26,13 @@ {% endif %}
    -
    - -
    +
    + +
    - +

    @@ -51,7 +51,11 @@ {% for uc in collections %} + {% if g.user_session.user_ob %} + {% else %} + + {% endif %} {{ loop.index }} {% if g.user_session.user_ob %} {{ uc.name }} diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index 1254ea6a..0d305559 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -275,29 +275,32 @@ {% if target_dataset.type == "ProbeSet" %} - var json_array = new Array(); + var json_array = []; for (i=0; i < table_json.length; i++){ - json_array.push({ - checkbox: table_json[i]["checkbox"], - index: table_json[i]["index"], - trait_id: table_json[i]["trait_id"], - symbol: table_json[i]["symbol"], - description: table_json[i]["description"], - location: table_json[i]["location"], - mean: table_json[i]["mean"], - lrs_score: table_json[i]["lrs_score"], - lrs_location: table_json[i]["lrs_location"], - additive: table_json[i]["additive"], - sample_r: table_json[i]["sample_r"], - num_overlap: table_json[i]["num_overlap"], - sample_p: table_json[i]["sample_p"], - lit_corr: table_json[i]["lit_corr"], - tissue_corr: table_json[i]["tissue_corr"] - }); - console.log("JSON_DATA:", json_array); + this_array = json_array + + var row_dict = {}; + row_dict.checkbox = table_json[i]["checkbox"] + row_dict.index = table_json[i]["index"] + row_dict.trait_id = table_json[i]["trait_id"] + row_dict.symbol = table_json[i]["symbol"] + row_dict.description = table_json[i]["description"] + row_dict.location = table_json[i]["location"] + row_dict.mean = table_json[i]["mean"] + row_dict.lrs_score = table_json[i]["lrs_score"] + row_dict.lrs_location = table_json[i]["lrs_location"] + row_dict.additive = table_json[i]["additive"] + row_dict.sample_r = table_json[i]["sample_r"] + row_dict.num_overlap = table_json[i]["num_overlap"] + row_dict.sample_p = table_json[i]["sample_p"] + row_dict.lit_corr = table_json[i]["lit_corr"] + row_dict.tissue_corr = table_json[i]["tissue_corr"] + this_array.push(row_dict); + json_array.concat(this_array); + //console.log("JSON_ARRAY:", json_array); } - //console.log("JSON_DATA:", json_array) + console.log("JSON_DATA:", json_array) $("#trait_table").tabulator({ data: json_array, diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index dcec2b9e..ab2e2aae 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -1,6 +1,6 @@
    {% if (use_pylmm_rqtl and dataset.group.species != "human") or use_plink_gemma %} -
    +