From ef38724c31567b56214026999a944f9088fe30b8 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 28 Jun 2020 11:23:27 -0500 Subject: make stains headers names horizontal --- wqflask/wqflask/templates/snp_browser.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index fb564b28..7019e943 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -195,7 +195,7 @@ <th data-export="{{ header }}">{{ header }}</th> {% endfor %} {% for strain in header_fields[1] %} - <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 15px;">{% for letter in strain %}<div style="transform: rotate(90deg);">{{ letter }}</div>{% endfor %}</th> + <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 15px;">{{ strain }}</th> {% endfor %} {% else %} {% for header in header_fields %} -- cgit v1.2.3 From 88715630c4d18d962a7473dcac7e34b1b9c098a0 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 28 Jun 2020 11:24:12 -0500 Subject: add DataTables pagination --- wqflask/wqflask/templates/snp_browser.html | 1 - 1 file changed, 1 deletion(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 7019e943..3b97963c 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -407,7 +407,6 @@ {% endif %} 'order': [[1, "asc" ]], 'sDom': "rtip", - 'iDisplayLength': 500, 'processing': true, 'language': { 'loadingRecords': ' ', -- cgit v1.2.3 From 73e3f354b0bf6accfd884f0fab8ef93f03be7945 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 28 Jun 2020 11:28:28 -0500 Subject: fix typo in check_if_in_gene function while querying for species_id = 0 --- wqflask/wqflask/snp_browser/snp_browser.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 6c3fcf53..a2fb7195 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -526,7 +526,6 @@ class SnpBrowser(object): the_rows.append(this_row) return the_rows - def include_record(self, domain, function, snp_source, conservation_score): """ Decide whether to add this record """ @@ -868,8 +867,6 @@ def get_gene_id_name_dict(species_id, gene_name_list): if len(results) > 0: for item in results: gene_id_name_dict[item[1]] = item[0] - else: - pass return gene_id_name_dict @@ -883,7 +880,7 @@ def check_if_in_gene(species_id, chr, mb): query = """SELECT geneId,geneSymbol FROM GeneList WHERE chromosome = '{0}' AND - (txStart < {1} AND txEnd > {1}); """.format(species_id, chr, mb) + (txStart < {1} AND txEnd > {1}); """.format(chr, mb) result = g.db.execute(query).fetchone() -- cgit v1.2.3 From 429aff0920b1fddf71e4547c35a726b11e6713a0 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Tue, 30 Jun 2020 14:14:53 -0500 Subject: 500 rows per page for DataTables --- wqflask/wqflask/templates/snp_browser.html | 1 + 1 file changed, 1 insertion(+) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 3b97963c..7019e943 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -407,6 +407,7 @@ {% endif %} 'order': [[1, "asc" ]], 'sDom': "rtip", + 'iDisplayLength': 500, 'processing': true, 'language': { 'loadingRecords': ' ', -- cgit v1.2.3 From 776ccfbb2fc5a6e85c7a41efd92b33b0e27de68a Mon Sep 17 00:00:00 2001 From: uditgulati Date: Tue, 30 Jun 2020 14:56:22 -0500 Subject: reduce gap between first and second column in form --- wqflask/wqflask/templates/snp_browser.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 7019e943..73359835 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -15,7 +15,7 @@ <input type="hidden" name="first_run" value="{{ first_run }}"> <input type="hidden" name="chosen_strains_mouse" value="{{ chosen_strains_mouse|join(",") }}"> <input type="hidden" name="chosen_strains_rat" value="{{ chosen_strains_rat|join(",") }}"> - <div class="col-xs-4" style="padding-left: 0px;"> + <div class="col-xs-4" style="width: 260px; padding-left: 30px; padding-right: 0px;"> <div class="form-group row" style="margin-bottom: 5px;"> <label for="snp_or_indel" style="text-align: right;" class="col-xs-4 col-form-label"><b>Type:</b></label> <div class="col-xs-8"> @@ -74,7 +74,7 @@ </div> </div> </div> - <div class="col-xs-4" style="padding-left: 0px;"> + <div class="col-xs-4" style="width: 310px; padding-left: 0px; padding-right: 20px;"> <div class="form-group row" style="margin-bottom: 10px;"> <label for="strains" style="text-align: right;" class="col-xs-4 col-form-label"><b>Strains:</b></label> <div class="col-xs-8"> @@ -108,7 +108,7 @@ </div> </div> </div> - <div class="col-xs-4" style="padding-left: 20px;"> + <div class="col-xs-4" style="width: 310px; padding-left: 20px;"> <div class="form-group row" style="margin-bottom: 5px;"> <label for="domain" style="text-align: right;" class="col-xs-4 col-form-label"><b>Domain:</b></label> <div class="col-xs-8"> -- cgit v1.2.3 From 3a792dbe74ab181d2fa9582f67c99b68ffad0c10 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Tue, 30 Jun 2020 15:38:04 -0500 Subject: align numeric data values to right, categorial values to center --- wqflask/wqflask/templates/snp_browser.html | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 73359835..816d5f0f 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -272,7 +272,8 @@ return '<input type="checkbox" name="trait_check">' } }, { - 'data': 'index' + 'data': 'index', + 'className': 'dt-body-right' }, { 'data': null, 'render': function(data, type, row, meta) { @@ -283,9 +284,11 @@ } } }, { - 'data': 'chr' + 'data': 'chr', + 'className': 'dt-body-center' }, { - 'data': 'mb_formatted' + 'data': 'mb_formatted', + 'className': 'dt-body-right' }, { 'data': 'alleles' }, {% if empty_columns['snp_source'] == "true" %}{ @@ -298,7 +301,8 @@ } } }, {% endif %} {% if empty_columns['conservation_score'] == "true" %}{ - 'data': 'conservation_score' + 'data': 'conservation_score', + 'className': 'dt-body-right' }, {% endif %} {% if empty_columns['gene_name'] == "true" %}{ 'data': null, 'render': function(data, type, row, meta) { @@ -383,21 +387,26 @@ return '<input type="checkbox" name="trait_check">' } }, { - 'data': 'index' + 'data': 'index', + 'className': 'dt-body-right' }, { 'data': 'indel_name' }, { 'data': 'indel_type' }, { - 'data': 'indel_chr' + 'data': 'indel_chr', + 'className': 'dt-body-center' }, { - 'data': 'indel_mb_s' + 'data': 'indel_mb_s', + 'className': 'dt-body-right' }, { - 'data': 'indel_mb_e' + 'data': 'indel_mb_e', + 'className': 'dt-body-right' }, { 'data': 'indel_strand' }, { - 'data': 'indel_size' + 'data': 'indel_size', + 'className': 'dt-body-right' }, { 'data': 'indel_sequence' }, { -- cgit v1.2.3 From f7b7950533f52e418c2be569cca409ae1fb3faf0 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Tue, 30 Jun 2020 16:48:02 -0500 Subject: rotate strain headers 270 deg --- wqflask/wqflask/templates/snp_browser.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 816d5f0f..36f893bc 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -195,7 +195,7 @@ <th data-export="{{ header }}">{{ header }}</th> {% endfor %} {% for strain in header_fields[1] %} - <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 15px;">{{ strain }}</th> + <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 12px;">{% for letter in strain|reverse %}<div style="transform: rotate(270deg);">{{ letter }}</div>{% endfor %}</th> {% endfor %} {% else %} {% for header in header_fields %} -- cgit v1.2.3 From 7a4068d6d46d923c30316887e1d20f2fa6caa859 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Fri, 10 Jul 2020 10:15:22 -0500 Subject: add export to CSV button to export current page --- wqflask/wqflask/templates/snp_browser.html | 43 +++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 36f893bc..284b55c5 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -107,6 +107,12 @@ </div> </div> </div> + <div class="form-group row"> + <label class="col-xs-4 col-form-label"></label> + <div class="col-xs-8" style="margin-top: 65px;"> + <input class="btn btn-primary" type="button" name="export_csv" value="Export to CSV"> + </div> + </div> </div> <div class="col-xs-4" style="width: 310px; padding-left: 20px;"> <div class="form-group row" style="margin-bottom: 5px;"> @@ -192,14 +198,14 @@ <th></th> {% if header_fields|length == 2 %} {% for header in header_fields[0] %} - <th data-export="{{ header }}">{{ header }}</th> + <th data-export="{{ header }}" name="{{ header }}">{{ header }}</th> {% endfor %} {% for strain in header_fields[1] %} - <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 12px;">{% for letter in strain|reverse %}<div style="transform: rotate(270deg);">{{ letter }}</div>{% endfor %}</th> + <th data-export="{{ strain }}" name="{{ strain }}" style="align: center; text-align: center; line-height: 12px;">{% for letter in strain|reverse %}<div style="transform: rotate(270deg);">{{ letter }}</div>{% endfor %}</th> {% endfor %} {% else %} {% for header in header_fields %} - <th data-export="{{ header }}">{{ header }}</th> + <th data-export="{{ header }}" name="{{ header }}">{{ header }}</th> {% endfor %} {% endif %} </tr> @@ -518,6 +524,37 @@ }); $("input[name=chosen_strains]").val(strain_list.join(",")); }); + + $("input[name=export_csv]").click(function() { + var csv = []; + var rows = document.querySelectorAll("table tr"); + + var headers = []; + var col_header = rows[0].querySelectorAll("th"); + console.log(col_header.length); + for(var i = 1; i < col_header.length; i++) { + console.log(col_header[i].getAttribute("name")); + headers.push(col_header[i].getAttribute("name")); + } + csv.push(headers.join(",")); + + for (var i = 1; i < rows.length; i++) { + var row = [], cols = rows[i].querySelectorAll("td"); + + for (var j = 1; j < cols.length; j++) + row.push(cols[j].innerText); + + csv.push(row.join(",")); + } + + var csvFile = new Blob([csv.join("\n")], {type: "text/csv"}); + var downloadLink = document.createElement("a"); + downloadLink.download = "hello.csv"; + downloadLink.href = window.URL.createObjectURL(csvFile); + downloadLink.style.display = "none"; + document.body.appendChild(downloadLink); + downloadLink.click(); + }); </script> {% endblock %} -- cgit v1.2.3 From f99b69155d35900a75c000fbb79f6bcfb3fa6ff1 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Fri, 10 Jul 2020 10:30:04 -0500 Subject: export only checked rows to csv; update csv file name --- wqflask/wqflask/templates/snp_browser.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 284b55c5..83606804 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -531,25 +531,27 @@ var headers = []; var col_header = rows[0].querySelectorAll("th"); - console.log(col_header.length); for(var i = 1; i < col_header.length; i++) { - console.log(col_header[i].getAttribute("name")); headers.push(col_header[i].getAttribute("name")); } csv.push(headers.join(",")); for (var i = 1; i < rows.length; i++) { var row = [], cols = rows[i].querySelectorAll("td"); + var checkBox = rows[i].querySelector("input"); + console.log(checkBox); - for (var j = 1; j < cols.length; j++) - row.push(cols[j].innerText); + if(checkBox.checked == true) { + for (var j = 1; j < cols.length; j++) + row.push(cols[j].innerText); - csv.push(row.join(",")); + csv.push(row.join(",")); + } } var csvFile = new Blob([csv.join("\n")], {type: "text/csv"}); var downloadLink = document.createElement("a"); - downloadLink.download = "hello.csv"; + downloadLink.download = "variant_data.csv"; downloadLink.href = window.URL.createObjectURL(csvFile); downloadLink.style.display = "none"; document.body.appendChild(downloadLink); -- cgit v1.2.3 From 349b395375703e727465a1f05f4a5e2d4fc64d2a Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 19 Jul 2020 17:21:15 -0500 Subject: add server side processing due to large tables in DataTables; work on server-side processing API pending for sorting, paging etc --- wqflask/wqflask/snp_browser/snp_browser.py | 39 ++++++++++++++++++++++-------- wqflask/wqflask/templates/snp_browser.html | 26 +++++++++++++++----- wqflask/wqflask/views.py | 10 ++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index a2fb7195..9ae8892b 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -4,7 +4,7 @@ import string from PIL import (Image) from utility.logger import getLogger -logger = getLogger(__name__ ) +logger = getLogger(__name__) from base import species from base import webqtlConfig @@ -14,16 +14,16 @@ class SnpBrowser(object): def __init__(self, start_vars): self.strain_lists = get_browser_sample_lists() self.initialize_parameters(start_vars) - self.limit_number = 10000 if self.first_run == "false": self.filtered_results = self.get_browser_results() + self.table_rows = self.get_table_rows() + self.rows_count = len(self.table_rows) - if len(self.filtered_results) <= self.limit_number: - self.table_rows = self.get_table_rows() - else: - self.empty_columns = None - self.table_rows = [] + del self.filtered_results + + if 'sEcho' not in start_vars: + self.table_rows = self.table_rows[:500] if self.limit_strains == "true": self.header_fields, self.empty_field_count = get_header_list(variant_type = self.variant_type, strains = self.chosen_strains, empty_columns = self.empty_columns) @@ -380,7 +380,7 @@ class SnpBrowser(object): the_rows = [] for i, result in enumerate(self.filtered_results): - this_row = [] + this_row = {} if self.variant_type == "SNP": snp_name, rs, chr, mb, alleles, gene, transcript, exon, domain, function, function_details, snp_source, conservation_score, snp_id = result[:14] allele_value_list = result[14:] @@ -520,8 +520,6 @@ class SnpBrowser(object): "source_name": str(source_name) } #this_row = [indel_name, indel_chr, indel_mb_s, indel_mb_e, indel_strand, indel_type, indel_size, indel_sequence, source_name] - else: - this_row = {} the_rows.append(this_row) @@ -643,6 +641,27 @@ class SnpBrowser(object): #for i in range(n_click): # href = url_for('snp_browser', first_run="false", chosen_strains_mouse=self.chosen_strains_mouse, chosen_strains_rat=self.chosen_strains_rat, variant=self.variant_type, species=self.species_name, gene_name=self.gene_name, chr=self.chr, start_mb=self.start_mb, end_mb=self.end_mb, limit_strains=self.limit_strains, domain=self.domain, function=self.function, criteria=self.criteria, score=self.score, diff_alleles=self.diff_alleles) +class SnpPage(object): + + def __init__(self, start_vars): + self.snp_browser = SnpBrowser(start_vars) + # self.table_rows = self.filter_rows() + self.rows_count = self.snp_browser.rows_count + self.sEcho = start_vars['sEcho'] + + def filter_rows(self): + pass + + def get_page(self): + output = {} + output['sEcho'] = str(self.sEcho) + output['iTotalRecords'] = str(self.rows_count) + output['iTotalDisplayRecords'] = str(100) + # logger.info(len(self.table_rows), type(self.table_rows), self.table_rows[0]) + logger.info(self.snp_browser.rows_count, len(self.snp_browser.table_rows)) + output['data'] = self.snp_browser.table_rows[:100] + return output + def get_browser_sample_lists(species_id=1): strain_lists = {} mouse_strain_list = [] diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 83606804..f3e928af 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -188,10 +188,7 @@ </div> <div style="margin-top: 20px;"> - {% if filtered_results is defined %} - {% if filtered_results|length > limit_number %} - There are more than 10000 results. Consider limiting your search to a smaller range. - {% else %} + {% if table_rows is defined %} <table class="dataTable cell-border nowrap" id="results_table" style="float: left;"> <thead> <tr> @@ -214,7 +211,6 @@ <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td> </tbody> </table> - {% endif %} {% endif %} </div> </div> @@ -229,11 +225,23 @@ <script type='text/javascript'> var json_rows = {{ table_rows|safe }}; + var json_rows_count = {{ rows_count|safe }}; var empty_columns = {{ empty_columns|safe }}; </script> <script language="javascript"> + var getParams = function(url) { + var parser = document.createElement('a'); + parser.href = url; + var params = parser.search.substring(1); + console.log(params); + if(params.length > 0) { + return ('?'+params); + } + return params; + }; + var substringMatcher = function(strs) { return function findMatches(q, cb) { var matches, substringRegex; @@ -266,7 +274,7 @@ source: substringMatcher(rat_genes) }); - {% if filtered_results is defined %} + {% if table_rows is defined %} $("#results_table").DataTable( { 'data': json_rows, {% if variant_type == "SNP" %} @@ -423,6 +431,10 @@ 'order': [[1, "asc" ]], 'sDom': "rtip", 'iDisplayLength': 500, + 'bServerSide': true, + 'bProcessing': true, + 'sAjaxSource': '/snp_browser_table'+getParams(window.location.href), + 'deferLoading': json_rows_count, 'processing': true, 'language': { 'loadingRecords': ' ', @@ -525,6 +537,8 @@ $("input[name=chosen_strains]").val(strain_list.join(",")); }); + + $("input[name=export_csv]").click(function() { var csv = []; var rows = document.querySelectorAll("table tr"); diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 08673f79..a2c66d53 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -897,6 +897,7 @@ def corr_scatter_plot_page(): def snp_browser_page(): logger.info(request.url) template_vars = snp_browser.SnpBrowser(request.args) + logger.info(template_vars.__dict__.keys()) return render_template("snp_browser.html", **template_vars.__dict__) @@ -906,6 +907,15 @@ def db_info_page(): return render_template("info_page.html", **template_vars.__dict__) +@app.route("/snp_browser_table", methods=('GET',)) +def snp_browser_table(): + logger.info(request.url) + logger.info(request.args) + + current_page = snp_browser.SnpPage(request.args).get_page() + + return flask.jsonify(current_page) + @app.route("/tutorial/WebQTLTour", methods=('GET',)) def tutorial_page(): #ZS: Currently just links to GN1 -- cgit v1.2.3 From bad336d0d2282f6eaadbcd0fe21afaaaf5342890 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Thu, 23 Jul 2020 06:34:07 -0500 Subject: server side processing working for snp browser --- wqflask/wqflask/snp_browser/snp_browser.py | 92 ++++++++++++++++++++++++------ wqflask/wqflask/templates/snp_browser.html | 7 +-- wqflask/wqflask/views.py | 4 +- 3 files changed, 80 insertions(+), 23 deletions(-) diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 9ae8892b..116da149 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -23,12 +23,12 @@ class SnpBrowser(object): del self.filtered_results if 'sEcho' not in start_vars: - self.table_rows = self.table_rows[:500] + self.table_rows = [] if self.limit_strains == "true": - self.header_fields, self.empty_field_count = get_header_list(variant_type = self.variant_type, strains = self.chosen_strains, empty_columns = self.empty_columns) + self.header_fields, self.empty_field_count, self.header_data_names = get_header_list(variant_type = self.variant_type, strains = self.chosen_strains, empty_columns = self.empty_columns) else: - self.header_fields, self.empty_field_count = get_header_list(variant_type = self.variant_type, strains = self.strain_lists, species = self.species_name, empty_columns = self.empty_columns) + self.header_fields, self.empty_field_count, self.header_data_names = get_header_list(variant_type = self.variant_type, strains = self.strain_lists, species = self.species_name, empty_columns = self.empty_columns) def initialize_parameters(self, start_vars): if 'first_run' in start_vars: @@ -643,23 +643,75 @@ class SnpBrowser(object): class SnpPage(object): - def __init__(self, start_vars): - self.snp_browser = SnpBrowser(start_vars) - # self.table_rows = self.filter_rows() - self.rows_count = self.snp_browser.rows_count - self.sEcho = start_vars['sEcho'] + def __init__(self, request): + self.request_values = request + self.sEcho = self.request_values['sEcho'] - def filter_rows(self): - pass + self.snp_browser = SnpBrowser(request) + self.rows_count = self.snp_browser.rows_count + self.table_rows = self.snp_browser.table_rows + self.header_data_names = self.snp_browser.header_data_names + + logger.info(self.table_rows[0]) + + self.sort_rows() + self.paginate_rows() + + def sort_rows(self): + ''' + Sorts the rows taking in to account the column (or columns) that the + user has selected. + ''' + def is_reverse(str_direction): + ''' Maps the 'desc' and 'asc' words to True or False. ''' + return True if str_direction == 'desc' else False + + if (self.request_values['iSortCol_0'] != "") and (int(self.request_values['iSortingCols']) > 0): + for i in range(0, int(self.request_values['iSortingCols'])): + column_number = int(self.request_values['iSortCol_' + str(i)]) + column_name = self.header_data_names[column_number - 1] + sort_direction = self.request_values['sSortDir_' + str(i)] + self.table_rows = sorted(self.table_rows, + key=lambda x: x[column_name], + reverse=is_reverse(sort_direction)) + + def paginate_rows(self): + ''' + Selects a subset of the filtered and sorted data based on if the table + has pagination, the current page and the size of each page. + ''' + def requires_pagination(): + ''' Check if the table is going to be paginated ''' + if self.request_values['iDisplayStart'] != "": + if int(self.request_values['iDisplayLength']) != -1: + return True + return False + + if not requires_pagination(): + return + + start = int(self.request_values['iDisplayStart']) + length = int(self.request_values['iDisplayLength']) + + # if search returns only one page + if len(self.table_rows) <= length: + # display only one page + self.table_rows = self.table_rows[start:] + else: + limit = -len(self.table_rows) + start + length + if limit < 0: + # display pagination + self.table_rows = self.table_rows[start:limit] + else: + # display last page of pagination + self.table_rows = self.table_rows[start:] def get_page(self): output = {} output['sEcho'] = str(self.sEcho) - output['iTotalRecords'] = str(self.rows_count) - output['iTotalDisplayRecords'] = str(100) - # logger.info(len(self.table_rows), type(self.table_rows), self.table_rows[0]) - logger.info(self.snp_browser.rows_count, len(self.snp_browser.table_rows)) - output['data'] = self.snp_browser.table_rows[:100] + output['iTotalRecords'] = str(float('Nan')) + output['iTotalDisplayRecords'] = str(self.rows_count) + output['data'] = self.table_rows return output def get_browser_sample_lists(species_id=1): @@ -692,9 +744,13 @@ def get_header_list(variant_type, strains, species = None, empty_columns = None) empty_field_count = 0 #ZS: This is an awkward way of letting the javascript know the index where the allele value columns start; there's probably a better way of doing this header_fields = [] + header_data_names = [] if variant_type == "SNP": header_fields.append(['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'Source', 'ConScore', 'Gene', 'Transcript', 'Exon', 'Domain 1', 'Domain 2', 'Function', 'Details']) + header_data_names = ['index', 'snp_name', 'chr', 'mb_formatted', 'alleles', 'snp_source', 'conservation_score', 'gene_name', 'transcript', 'exon', 'domain_1', 'domain_2', 'function', 'function_details'] + header_fields.append(strain_list) + header_data_names += strain_list if empty_columns != None: if empty_columns['snp_source'] == "false": @@ -721,11 +777,15 @@ def get_header_list(variant_type, strains, species = None, empty_columns = None) if empty_columns['function_details'] == "false": empty_field_count += 1 header_fields[0].remove('Details') + + for col in empty_columns: + header_data_names.remove(col) elif variant_type == "InDel": header_fields = ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'] + header_data_names = ['index', 'indel_name', 'indel_type', 'indel_chr', 'indel_mb_s', 'indel_mb_e', 'indel_strand', 'indel_size', 'indel_sequence', 'source_name'] - return header_fields, empty_field_count + return header_fields, empty_field_count, header_data_names def get_effect_details_by_category(effect_name = None, effect_value = None): gene_list = [] diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index f3e928af..cbc12e06 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -276,7 +276,6 @@ {% if table_rows is defined %} $("#results_table").DataTable( { - 'data': json_rows, {% if variant_type == "SNP" %} 'columns': [ { @@ -432,10 +431,10 @@ 'sDom': "rtip", 'iDisplayLength': 500, 'bServerSide': true, - 'bProcessing': true, 'sAjaxSource': '/snp_browser_table'+getParams(window.location.href), - 'deferLoading': json_rows_count, - 'processing': true, + 'infoCallback': function(settings, start, end, max, total, pre) { + return "Showing " + start + " to " + (start + this.api().data().length - 1) + " of " + total + " entries"; + }, 'language': { 'loadingRecords': ' ', 'processing': 'Loading...' diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index a2c66d53..8e7f6ec3 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -909,9 +909,7 @@ def db_info_page(): @app.route("/snp_browser_table", methods=('GET',)) def snp_browser_table(): - logger.info(request.url) - logger.info(request.args) - + logger.info(request.url) current_page = snp_browser.SnpPage(request.args).get_page() return flask.jsonify(current_page) -- cgit v1.2.3 From 29902d1c60b338c1c06289f9ea1cae5a61e28d4b Mon Sep 17 00:00:00 2001 From: uditgulati Date: Thu, 6 Aug 2020 08:48:53 -0500 Subject: fix issue with column sort; put 'Gene' column data in one line --- wqflask/wqflask/snp_browser/snp_browser.py | 25 ++++++++++++------------- wqflask/wqflask/templates/snp_browser.html | 6 +----- wqflask/wqflask/views.py | 3 +-- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 116da149..58c90f11 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -368,15 +368,15 @@ class SnpBrowser(object): #ZS: list of booleans representing which columns are entirely empty, so they aren't displayed on the page; only including ones that are sometimes empty (since there's always a location, etc) self.empty_columns = { - "snp_source": "false", - "conservation_score": "false", - "gene_name": "false", - "transcript": "false", - "exon": "false", - "domain_2": "false", - "function": "false", - "function_details": "false" - } + "snp_source": "false", + "conservation_score": "false", + "gene_name": "false", + "transcript": "false", + "exon": "false", + "domain_2": "false", + "function": "false", + "function_details": "false" + } the_rows = [] for i, result in enumerate(self.filtered_results): @@ -651,8 +651,6 @@ class SnpPage(object): self.rows_count = self.snp_browser.rows_count self.table_rows = self.snp_browser.table_rows self.header_data_names = self.snp_browser.header_data_names - - logger.info(self.table_rows[0]) self.sort_rows() self.paginate_rows() @@ -778,8 +776,9 @@ def get_header_list(variant_type, strains, species = None, empty_columns = None) empty_field_count += 1 header_fields[0].remove('Details') - for col in empty_columns: - header_data_names.remove(col) + for col in empty_columns.keys(): + if empty_columns[col] == "false": + header_data_names.remove(col) elif variant_type == "InDel": header_fields = ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'] diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index cbc12e06..96cd7247 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -320,7 +320,7 @@ 'data': null, 'render': function(data, type, row, meta) { if (data.gene_name != "") { - return '<i>' + data.gene_name + '</i><br><a href="' + data.gene_link + '">NCBI</a>' + return '<i>' + data.gene_name + '</i>, <a href="' + data.gene_link + '">NCBI</a>' } else { return data.gene_name } @@ -434,10 +434,6 @@ 'sAjaxSource': '/snp_browser_table'+getParams(window.location.href), 'infoCallback': function(settings, start, end, max, total, pre) { return "Showing " + start + " to " + (start + this.api().data().length - 1) + " of " + total + " entries"; - }, - 'language': { - 'loadingRecords': ' ', - 'processing': 'Loading...' } }); {% endif %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 8e7f6ec3..12ebf595 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -897,7 +897,6 @@ def corr_scatter_plot_page(): def snp_browser_page(): logger.info(request.url) template_vars = snp_browser.SnpBrowser(request.args) - logger.info(template_vars.__dict__.keys()) return render_template("snp_browser.html", **template_vars.__dict__) @@ -909,7 +908,7 @@ def db_info_page(): @app.route("/snp_browser_table", methods=('GET',)) def snp_browser_table(): - logger.info(request.url) + logger.info(request.url) current_page = snp_browser.SnpPage(request.args).get_page() return flask.jsonify(current_page) -- cgit v1.2.3 From ace7b2d323c4f157f4d0e770dd948189562fa76b Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 16:03:24 -0500 Subject: remove createdRow callback and move color rendering to column defs to speedup rendering --- wqflask/wqflask/templates/snp_browser.html | 76 +++++++++++++++--------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 96cd7247..dad86459 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -227,10 +227,44 @@ var json_rows = {{ table_rows|safe }}; var json_rows_count = {{ rows_count|safe }}; var empty_columns = {{ empty_columns|safe }}; + + var remain_field_count = {{ 15 - empty_field_count }}; + var total_field_count = {{ 15 - empty_field_count }} + {{ allele_list|length }}; </script> <script language="javascript"> + var getColor = function(allele) { + switch (allele) { + case "A": + return ('A_allele_color'); + break; + case "C": + return ('C_allele_color'); + break; + case "T": + return ('T_allele_color'); + break; + case "G": + return ('G_allele_color'); + break; + case "t": + return ('t_allele_color'); + break; + case "c": + return ('c_allele_color'); + break; + case "a": + return ('a_allele_color'); + break; + case "g": + return ('g_allele_color'); + break; + default: + return ('default_allele_color'); + } + } + var getParams = function(url) { var parser = document.createElement('a'); parser.href = url; @@ -280,6 +314,7 @@ 'columns': [ { 'data': null, + 'className': 'dt-body-center', 'orderable': false, 'render': function(data, type, row, meta) { return '<input type="checkbox" name="trait_check">' @@ -308,7 +343,7 @@ 'data': null, 'render': function(data, type, row, meta) { if (data.snp_source == "Sanger/UCLA") { - return '<a href="' + data.source_urls[0] + '">Sanger</a><a href="' + data.source_urls[1] + '">UCLA</a>' + return '<a href="' + data.source_urls[0] + '">Sanger</a>, <a href="' + data.source_urls[1] + '">UCLA</a>' } else { return data.snp_source } @@ -347,6 +382,7 @@ }, {% endif %} {% for item in allele_list %} { 'data': null, 'orderable': false, + 'className': 'dt-body-center ' + getColor('{{ item }}'), 'render': function(data, type, row, meta) { if (typeof data.allele_value_list[{{ loop.index - 1 }}][0] !== "undefined") { return data.allele_value_list[{{ loop.index - 1 }}][0] @@ -356,42 +392,6 @@ } }{% if loop.index < allele_list|length %},{% endif %}{% endfor %} ], - 'createdRow': function( row, data, dataIndex) { - $('td', row).eq(0).attr("style", "text-align: center; padding: 4px 10px 2px 10px;"); - $('td', row).eq(1).attr("align", "right"); - for (i = {{ 15 - empty_field_count }}; i < ({{ 15 - empty_field_count }} + {{ allele_list|length }}); i++) { - var this_allele = $('td', row).eq(i).text(); - $('td', row).eq(i).attr("style", "text-align: center; padding: 4px 10px 2px 10px;"); - switch (this_allele) { - case "A": - $('td', row).eq(i).addClass('A_allele_color'); - break; - case "C": - $('td', row).eq(i).addClass('C_allele_color'); - break; - case "T": - $('td', row).eq(i).addClass('T_allele_color'); - break; - case "G": - $('td', row).eq(i).addClass('G_allele_color'); - break; - case "t": - $('td', row).eq(i).addClass('t_allele_color'); - break; - case "c": - $('td', row).eq(i).addClass('c_allele_color'); - break; - case "a": - $('td', row).eq(i).addClass('a_allele_color'); - break; - case "g": - $('td', row).eq(i).addClass('g_allele_color'); - break; - default: - $('td', row).eq(i).addClass('default_allele_color'); - } - } - }, {% else %} 'columns': [ { @@ -429,7 +429,7 @@ {% endif %} 'order': [[1, "asc" ]], 'sDom': "rtip", - 'iDisplayLength': 500, + 'iDisplayLength': 100, 'bServerSide': true, 'sAjaxSource': '/snp_browser_table'+getParams(window.location.href), 'infoCallback': function(settings, start, end, max, total, pre) { -- cgit v1.2.3 From 1caac2a2337d1300e197892cf2a260867998e88e Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 16:04:55 -0500 Subject: remove debug log --- wqflask/wqflask/templates/snp_browser.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index dad86459..1a2da20f 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -269,7 +269,6 @@ var parser = document.createElement('a'); parser.href = url; var params = parser.search.substring(1); - console.log(params); if(params.length > 0) { return ('?'+params); } @@ -548,7 +547,6 @@ for (var i = 1; i < rows.length; i++) { var row = [], cols = rows[i].querySelectorAll("td"); var checkBox = rows[i].querySelector("input"); - console.log(checkBox); if(checkBox.checked == true) { for (var j = 1; j < cols.length; j++) -- cgit v1.2.3 From 876b95a8e1ad5944105b8d23ae362415011239b5 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 16:15:02 -0500 Subject: cell rendering cannot be in columnDef, optimised createdRow --- wqflask/wqflask/templates/snp_browser.html | 68 +++++++++++++++--------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 1a2da20f..c7923be6 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -224,8 +224,6 @@ <script language="javascript" type="text/javascript" src="/static/new/javascript/typeahead_rn6.json"></script> <script type='text/javascript'> - var json_rows = {{ table_rows|safe }}; - var json_rows_count = {{ rows_count|safe }}; var empty_columns = {{ empty_columns|safe }}; var remain_field_count = {{ 15 - empty_field_count }}; @@ -234,37 +232,6 @@ <script language="javascript"> - var getColor = function(allele) { - switch (allele) { - case "A": - return ('A_allele_color'); - break; - case "C": - return ('C_allele_color'); - break; - case "T": - return ('T_allele_color'); - break; - case "G": - return ('G_allele_color'); - break; - case "t": - return ('t_allele_color'); - break; - case "c": - return ('c_allele_color'); - break; - case "a": - return ('a_allele_color'); - break; - case "g": - return ('g_allele_color'); - break; - default: - return ('default_allele_color'); - } - } - var getParams = function(url) { var parser = document.createElement('a'); parser.href = url; @@ -381,7 +348,7 @@ }, {% endif %} {% for item in allele_list %} { 'data': null, 'orderable': false, - 'className': 'dt-body-center ' + getColor('{{ item }}'), + 'className': 'dt-body-center', 'render': function(data, type, row, meta) { if (typeof data.allele_value_list[{{ loop.index - 1 }}][0] !== "undefined") { return data.allele_value_list[{{ loop.index - 1 }}][0] @@ -391,6 +358,39 @@ } }{% if loop.index < allele_list|length %},{% endif %}{% endfor %} ], + 'createdRow': function(row, data, dataIndex) { + for (i = remain_field_count; i < total_field_count; i++) { + var this_allele = $('td', row).eq(i).text(); + switch (this_allele) { + case "A": + $('td', row).eq(i).addClass('A_allele_color'); + break; + case "C": + $('td', row).eq(i).addClass('C_allele_color'); + break; + case "T": + $('td', row).eq(i).addClass('T_allele_color'); + break; + case "G": + $('td', row).eq(i).addClass('G_allele_color'); + break; + case "t": + $('td', row).eq(i).addClass('t_allele_color'); + break; + case "c": + $('td', row).eq(i).addClass('c_allele_color'); + break; + case "a": + $('td', row).eq(i).addClass('a_allele_color'); + break; + case "g": + $('td', row).eq(i).addClass('g_allele_color'); + break; + default: + $('td', row).eq(i).addClass('default_allele_color'); + } + } + }, {% else %} 'columns': [ { -- cgit v1.2.3 From f52499653858512320ae17a2ff48671d82fc31fb Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 17:11:03 -0500 Subject: move SnpPage to a generic class ServerSide --- wqflask/wqflask/server_side.py | 74 ++++++++++++++++++++++++++++++ wqflask/wqflask/snp_browser/snp_browser.py | 71 ---------------------------- wqflask/wqflask/views.py | 17 ++++++- 3 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 wqflask/wqflask/server_side.py diff --git a/wqflask/wqflask/server_side.py b/wqflask/wqflask/server_side.py new file mode 100644 index 00000000..090720ec --- /dev/null +++ b/wqflask/wqflask/server_side.py @@ -0,0 +1,74 @@ +# handles server side table processing + + + +class ServerSide(object): + + def __init__(self, table_data, request_values): + self.request_values = request_values + self.sEcho = self.request_values['sEcho'] + + self.table_data = table_data + self.rows_count = self.table_data.rows_count + self.table_rows = self.table_data.table_rows + self.header_data_names = self.table_data.header_data_names + + self.sort_rows() + self.paginate_rows() + + def sort_rows(self): + ''' + Sorts the rows taking in to account the column (or columns) that the + user has selected. + ''' + def is_reverse(str_direction): + ''' Maps the 'desc' and 'asc' words to True or False. ''' + return True if str_direction == 'desc' else False + + if (self.request_values['iSortCol_0'] != "") and (int(self.request_values['iSortingCols']) > 0): + for i in range(0, int(self.request_values['iSortingCols'])): + column_number = int(self.request_values['iSortCol_' + str(i)]) + column_name = self.header_data_names[column_number - 1] + sort_direction = self.request_values['sSortDir_' + str(i)] + self.table_rows = sorted(self.table_rows, + key=lambda x: x[column_name], + reverse=is_reverse(sort_direction)) + + def paginate_rows(self): + ''' + Selects a subset of the filtered and sorted data based on if the table + has pagination, the current page and the size of each page. + ''' + def requires_pagination(): + ''' Check if the table is going to be paginated ''' + if self.request_values['iDisplayStart'] != "": + if int(self.request_values['iDisplayLength']) != -1: + return True + return False + + if not requires_pagination(): + return + + start = int(self.request_values['iDisplayStart']) + length = int(self.request_values['iDisplayLength']) + + # if search returns only one page + if len(self.table_rows) <= length: + # display only one page + self.table_rows = self.table_rows[start:] + else: + limit = -len(self.table_rows) + start + length + if limit < 0: + # display pagination + self.table_rows = self.table_rows[start:limit] + else: + # display last page of pagination + self.table_rows = self.table_rows[start:] + + def get_page(self): + output = {} + output['sEcho'] = str(self.sEcho) + output['iTotalRecords'] = str(float('Nan')) + output['iTotalDisplayRecords'] = str(self.rows_count) + output['data'] = self.table_rows + return output diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 58c90f11..a52399a2 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -641,77 +641,6 @@ class SnpBrowser(object): #for i in range(n_click): # href = url_for('snp_browser', first_run="false", chosen_strains_mouse=self.chosen_strains_mouse, chosen_strains_rat=self.chosen_strains_rat, variant=self.variant_type, species=self.species_name, gene_name=self.gene_name, chr=self.chr, start_mb=self.start_mb, end_mb=self.end_mb, limit_strains=self.limit_strains, domain=self.domain, function=self.function, criteria=self.criteria, score=self.score, diff_alleles=self.diff_alleles) -class SnpPage(object): - - def __init__(self, request): - self.request_values = request - self.sEcho = self.request_values['sEcho'] - - self.snp_browser = SnpBrowser(request) - self.rows_count = self.snp_browser.rows_count - self.table_rows = self.snp_browser.table_rows - self.header_data_names = self.snp_browser.header_data_names - - self.sort_rows() - self.paginate_rows() - - def sort_rows(self): - ''' - Sorts the rows taking in to account the column (or columns) that the - user has selected. - ''' - def is_reverse(str_direction): - ''' Maps the 'desc' and 'asc' words to True or False. ''' - return True if str_direction == 'desc' else False - - if (self.request_values['iSortCol_0'] != "") and (int(self.request_values['iSortingCols']) > 0): - for i in range(0, int(self.request_values['iSortingCols'])): - column_number = int(self.request_values['iSortCol_' + str(i)]) - column_name = self.header_data_names[column_number - 1] - sort_direction = self.request_values['sSortDir_' + str(i)] - self.table_rows = sorted(self.table_rows, - key=lambda x: x[column_name], - reverse=is_reverse(sort_direction)) - - def paginate_rows(self): - ''' - Selects a subset of the filtered and sorted data based on if the table - has pagination, the current page and the size of each page. - ''' - def requires_pagination(): - ''' Check if the table is going to be paginated ''' - if self.request_values['iDisplayStart'] != "": - if int(self.request_values['iDisplayLength']) != -1: - return True - return False - - if not requires_pagination(): - return - - start = int(self.request_values['iDisplayStart']) - length = int(self.request_values['iDisplayLength']) - - # if search returns only one page - if len(self.table_rows) <= length: - # display only one page - self.table_rows = self.table_rows[start:] - else: - limit = -len(self.table_rows) + start + length - if limit < 0: - # display pagination - self.table_rows = self.table_rows[start:limit] - else: - # display last page of pagination - self.table_rows = self.table_rows[start:] - - def get_page(self): - output = {} - output['sEcho'] = str(self.sEcho) - output['iTotalRecords'] = str(float('Nan')) - output['iTotalDisplayRecords'] = str(self.rows_count) - output['data'] = self.table_rows - return output - def get_browser_sample_lists(species_id=1): strain_lists = {} mouse_strain_list = [] diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 12ebf595..185517d3 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -27,7 +27,19 @@ import array import sqlalchemy from wqflask import app from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for, send_file - +<<<<<<< HEAD + +======= +from wqflask import group_manager +from wqflask import resource_manager +from wqflask import search_results +from wqflask import export_traits +from wqflask import gsearch +from wqflask import update_search_results +from wqflask import docs +from wqflask import news +from wqflask import server_side +>>>>>>> ed2afa4a (move SnpPage to a generic class ServerSide) from wqflask.submit_bnw import get_bnw_input from base.data_set import create_dataset, DataSet # Used by YAML in marker_regression from wqflask.show_trait import show_trait @@ -909,7 +921,8 @@ def db_info_page(): @app.route("/snp_browser_table", methods=('GET',)) def snp_browser_table(): logger.info(request.url) - current_page = snp_browser.SnpPage(request.args).get_page() + snp_table_data = snp_browser.SnpBrowser(request.args) + current_page = server_side.ServerSide(snp_table_data, request.args).get_page() return flask.jsonify(current_page) -- cgit v1.2.3 From c6e4083da1c78c923ba94b3057e1fe5e09f5b603 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 17:14:00 -0500 Subject: fix issue when empty_filed_count is not claculated --- wqflask/wqflask/templates/snp_browser.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index c7923be6..284a371a 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -226,8 +226,8 @@ <script type='text/javascript'> var empty_columns = {{ empty_columns|safe }}; - var remain_field_count = {{ 15 - empty_field_count }}; - var total_field_count = {{ 15 - empty_field_count }} + {{ allele_list|length }}; + var remain_field_count = 15 - {{ empty_field_count|safe }}; + var total_field_count = 15 - {{ empty_field_count|safe }} + {{ allele_list|safe|length }}; </script> <script language="javascript"> -- cgit v1.2.3 From 6b7dfb6ad280aa247c106f155fef81a03bd71c65 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 16 Aug 2020 17:30:13 -0500 Subject: make the page more color consistent --- wqflask/wqflask/static/new/css/snp_browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/css/snp_browser.css b/wqflask/wqflask/static/new/css/snp_browser.css index 30fe9a59..1dd332cb 100644 --- a/wqflask/wqflask/static/new/css/snp_browser.css +++ b/wqflask/wqflask/static/new/css/snp_browser.css @@ -18,7 +18,7 @@ table.dataTable thead .sorting_desc_disabled { table.dataTable thead th{ border-right: 1px solid white; color: white; - background-color: royalblue; + background-color: #369; } table.dataTable tbody td { -- cgit v1.2.3 From 0952e43989be3f24321932c3dd33fdc697c5703a Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 23 Aug 2020 14:47:39 -0500 Subject: replace var to let for variables in loops --- wqflask/wqflask/templates/snp_browser.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 284a371a..435a521c 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -539,17 +539,17 @@ var headers = []; var col_header = rows[0].querySelectorAll("th"); - for(var i = 1; i < col_header.length; i++) { + for(let i = 1; i < col_header.length; i++) { headers.push(col_header[i].getAttribute("name")); } csv.push(headers.join(",")); - for (var i = 1; i < rows.length; i++) { + for (let i = 1; i < rows.length; i++) { var row = [], cols = rows[i].querySelectorAll("td"); var checkBox = rows[i].querySelector("input"); if(checkBox.checked == true) { - for (var j = 1; j < cols.length; j++) + for (let j = 1; j < cols.length; j++) row.push(cols[j].innerText); csv.push(row.join(",")); -- cgit v1.2.3 From dfdff4934e423e2f4f626625a8bd1f45a64187b4 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 23 Aug 2020 16:13:11 -0500 Subject: update class name to ServerSideTable and add docstring --- wqflask/wqflask/server_side.py | 22 +++++++++++++++++++++- wqflask/wqflask/views.py | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/server_side.py b/wqflask/wqflask/server_side.py index 090720ec..d044d411 100644 --- a/wqflask/wqflask/server_side.py +++ b/wqflask/wqflask/server_side.py @@ -2,7 +2,27 @@ -class ServerSide(object): +class ServerSideTable(object): + ''' + This class is used to do server-side processing + on the DataTables table such as paginating, sorting, + filtering(not implemented) etc. This takes the load off + the client-side and reduces the size of data interchanged. + + Usage: + ServerSideTable(table_data, request_values) + where, + `table_data` must have data members + `rows_count` as number of rows in the table, + `table_rows` as data rows of the table, + `header_data_names` as headers names of the table. + + `request_values` must have request arguments values + including the DataTables server-side processing arguments. + + Have a look at snp_browser_table() function in + wqflask/wqflask/views.py for reference use. + ''' def __init__(self, table_data, request_values): self.request_values = request_values diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 185517d3..f0b78188 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -922,7 +922,7 @@ def db_info_page(): def snp_browser_table(): logger.info(request.url) snp_table_data = snp_browser.SnpBrowser(request.args) - current_page = server_side.ServerSide(snp_table_data, request.args).get_page() + current_page = server_side.ServerSideTable(snp_table_data, request.args).get_page() return flask.jsonify(current_page) -- cgit v1.2.3 From aa2d7a45fca8c6503a5de6cec7ce58d248144b9d Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 6 Sep 2020 10:38:19 -0500 Subject: add row highlight on checkbox checked state --- wqflask/wqflask/static/new/css/snp_browser.css | 4 ++++ wqflask/wqflask/templates/snp_browser.html | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/static/new/css/snp_browser.css b/wqflask/wqflask/static/new/css/snp_browser.css index 1dd332cb..a7942d2a 100644 --- a/wqflask/wqflask/static/new/css/snp_browser.css +++ b/wqflask/wqflask/static/new/css/snp_browser.css @@ -6,6 +6,10 @@ table.dataTable thead th { vertical-align: bottom; } +table.dataTable tbody tr.selected { + background-color: #ffee99; +} + table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index 435a521c..c312aee8 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -283,7 +283,7 @@ 'className': 'dt-body-center', 'orderable': false, 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="trait_check">' + return '<input type="checkbox" class="checkbox" id="variant_checkbox" onchange="onVarinatCheck(this)" name="trait_check">' } }, { 'data': 'index', @@ -396,7 +396,7 @@ { 'data': null, 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="trait_check">' + return '<input type="checkbox" class="checkbox" id="variant_checkbox" onchange="onVarinatCheck(this)" name="trait_check">' } }, { 'data': 'index', @@ -437,6 +437,19 @@ }); {% endif %} + function onVarinatCheck(checkboxElem) { + if (checkboxElem.checked) { + if (!checkboxElem.parentElement.parentElement.classList.contains('selected')) { + checkboxElem.parentElement.parentElement.classList.add('selected') + } + } + else { + if (checkboxElem.parentElement.parentElement.classList.contains('selected')) { + checkboxElem.parentElement.parentElement.classList.remove('selected') + } + } + } + $("#species_select").change(function() { this_species = $(this).val(); $("#strain_select").empty() -- cgit v1.2.3 From f3351f698c7961aa28578b90fa0c73a2e14f864d Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 6 Sep 2020 15:52:08 -0500 Subject: change arguments for ServerSideTable class --- wqflask/wqflask/server_side.py | 9 ++++----- wqflask/wqflask/views.py | 7 ++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/wqflask/wqflask/server_side.py b/wqflask/wqflask/server_side.py index d044d411..824b00aa 100644 --- a/wqflask/wqflask/server_side.py +++ b/wqflask/wqflask/server_side.py @@ -24,14 +24,13 @@ class ServerSideTable(object): wqflask/wqflask/views.py for reference use. ''' - def __init__(self, table_data, request_values): + def __init__(self, rows_count, table_rows, header_data_names, request_values): self.request_values = request_values self.sEcho = self.request_values['sEcho'] - self.table_data = table_data - self.rows_count = self.table_data.rows_count - self.table_rows = self.table_data.table_rows - self.header_data_names = self.table_data.header_data_names + self.rows_count = rows_count + self.table_rows = table_rows + self.header_data_names = header_data_names self.sort_rows() self.paginate_rows() diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index f0b78188..63570815 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -922,7 +922,12 @@ def db_info_page(): def snp_browser_table(): logger.info(request.url) snp_table_data = snp_browser.SnpBrowser(request.args) - current_page = server_side.ServerSideTable(snp_table_data, request.args).get_page() + current_page = server_side.ServerSideTable( + snp_table_data.rows_count, + snp_table_data.table_rows, + snp_table_data.header_data_names, + request.args, + ).get_page() return flask.jsonify(current_page) -- cgit v1.2.3 From 59e611827bf0621b2613cc29b3f4ba730ef3631e Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 13 Sep 2020 13:55:33 -0500 Subject: add server side processing to search table (/search and search_result_page.html) --- wqflask/wqflask/search_results.py | 16 +++++++++++----- wqflask/wqflask/templates/search_result_page.html | 21 ++++++++++++++++----- wqflask/wqflask/views.py | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index ce836ce2..8a5a7a80 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -28,9 +28,9 @@ class SearchResultPage(object): #maxReturn = 3000 def __init__(self, kw): - """This class gets invoked after hitting submit on the main menu (in -views.py). - + """ + This class gets invoked after hitting submit on the main menu (in + views.py). """ ########################################### @@ -86,7 +86,6 @@ views.py). else: self.gen_search_result() - def gen_search_result(self): """ Get the info displayed in the search result table from the set of results computed in @@ -155,7 +154,14 @@ views.py). trait_dict[key] = trait_dict[key].decode('utf-8') trait_list.append(trait_dict) - self.trait_list = json.dumps(trait_list) + self.trait_list = trait_list + + if this_trait.dataset.type == "ProbeSet": + self.header_data_names = ['index', 'display_name', 'symbol', 'description', 'location', 'mean', 'lrs_score', 'lrs_location', 'additive'] + elif this_trait.dataset.type == "Publish": + self.header_data_names = ['index', 'display_name', 'description', 'mean', 'authors', 'pubmed_text', 'lrs_score', 'lrs_location', 'additive'] + elif this_trait.dataset.type == "Geno": + self.header_data_names = ['index', 'display_name', 'location'] def search(self): """ diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 2318bfb8..7d36d32e 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -174,6 +174,16 @@ <script type="text/javascript" charset="utf-8"> $(document).ready( function () { + + var getParams = function(url) { + var parser = document.createElement('a'); + parser.href = url; + var params = parser.search.substring(1); + if(params.length > 0) { + return ('?'+params); + } + return params; + }; $('#trait_table tr').click(function(event) { if (event.target.type !== 'checkbox') { @@ -260,7 +270,7 @@ 'data': null, 'width': "25px", 'orderDataType': "dom-checkbox", - 'orderSequence': [ "desc", "asc"], + 'orderable': false, 'render': function(data, type, row, meta) { return '<input type="checkbox" name="searchResult" class="checkbox trait_checkbox" value="' + data.hmac + '">' } @@ -426,14 +436,15 @@ {% else %} 'sDom': "pitirp", {% endif %} - 'iDisplayLength': 500, + 'iDisplayLength': 10, 'deferRender': true, 'paging': true, 'orderClasses': true, 'processing': true, - 'language': { - 'loadingRecords': ' ', - 'processing': 'Loading...' + 'bServerSide': true, + 'sAjaxSource': '/search_table'+getParams(window.location.href), + 'infoCallback': function(settings, start, end, max, total, pre) { + return "Showing " + start + " to " + (start + this.api().data().length - 1) + " of " + total + " entries"; } } ); diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 63570815..2c1fa94b 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -234,6 +234,26 @@ def search_page(): else: return render_template("search_error.html") +@app.route("/search_table", methods=('GET',)) +def search_page_table(): + logger.info("in search_page table") + logger.info(request.url) + + logger.info("request.args is", request.args) + the_search = search_results.SearchResultPage(request.args) + + logger.info(type(the_search.trait_list)) + logger.info(the_search.trait_list) + + current_page = server_side.ServerSideTable( + len(the_search.trait_list), + the_search.trait_list, + the_search.header_data_names, + request.args, + ).get_page() + + return flask.jsonify(current_page) + @app.route("/gsearch", methods=('GET',)) def gsearchact(): logger.info(request.url) -- cgit v1.2.3 From e83bcab9f01ad1aa279f15e8a19700b802320f8b Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 13 Sep 2020 15:19:51 -0500 Subject: add pagination to show_trait tables and reduce css post processing for faster table loading --- wqflask/wqflask/templates/search_result_page.html | 2 +- wqflask/wqflask/views.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 7d36d32e..0bcbd492 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -436,7 +436,7 @@ {% else %} 'sDom': "pitirp", {% endif %} - 'iDisplayLength': 10, + 'iDisplayLength': 100, 'deferRender': true, 'paging': true, 'orderClasses': true, diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 2c1fa94b..2df7113e 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -27,9 +27,7 @@ import array import sqlalchemy from wqflask import app from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for, send_file -<<<<<<< HEAD -======= from wqflask import group_manager from wqflask import resource_manager from wqflask import search_results @@ -39,7 +37,6 @@ from wqflask import update_search_results from wqflask import docs from wqflask import news from wqflask import server_side ->>>>>>> ed2afa4a (move SnpPage to a generic class ServerSide) from wqflask.submit_bnw import get_bnw_input from base.data_set import create_dataset, DataSet # Used by YAML in marker_regression from wqflask.show_trait import show_trait -- cgit v1.2.3 From e106f5888cb4d761a6dcb71dc0273e461ef3c71a Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 13 Sep 2020 15:24:06 -0500 Subject: replace var with let in getParams() local variables --- wqflask/wqflask/templates/search_result_page.html | 4 ++-- wqflask/wqflask/templates/snp_browser.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 0bcbd492..6fe44d1a 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -176,9 +176,9 @@ $(document).ready( function () { var getParams = function(url) { - var parser = document.createElement('a'); + let parser = document.createElement('a'); parser.href = url; - var params = parser.search.substring(1); + let params = parser.search.substring(1); if(params.length > 0) { return ('?'+params); } diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index c312aee8..129d03c2 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -233,9 +233,9 @@ <script language="javascript"> var getParams = function(url) { - var parser = document.createElement('a'); + let parser = document.createElement('a'); parser.href = url; - var params = parser.search.substring(1); + let params = parser.search.substring(1); if(params.length > 0) { return ('?'+params); } -- cgit v1.2.3 From 30e8aaad9672151c4b6bc43ea386d0d39ca131a7 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 9 Dec 2020 16:18:07 -0600 Subject: Exchanged metadata and legend positions and made some changes to Y positioning for the metadata --- .../marker_regression/display_mapping_results.py | 39 +++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 08c2d750..9f778160 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -644,8 +644,10 @@ class DisplayMappingResults(object): yTopOffset = max(90, yTopOffset) else: if self.legendChecked: - if self.covariates != "" and self.controlLocus and self.doControl != "false": - yTopOffset = max(120, yTopOffset) + if (self.mapping_method == "gemma" or self.mapping_method == "rqtl_geno") and self.covariates != "": + yTopOffset = max(115, yTopOffset) + elif self.mapping_method == "rqtl_geno" and self.controlLocus and self.doControl != "false" and self.covariates != "": + yTopOffset = max(130, yTopOffset) else: yTopOffset = max(100, yTopOffset) else: @@ -859,13 +861,12 @@ class DisplayMappingResults(object): if self.legendChecked: startPosY = 30 - nCol = 2 smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) - leftOffset = xLeftOffset+(nCol-1)*200 + leftOffset = canvas.size[0] - xRightOffset - 190 im_drawer.rectangle( xy=((leftOffset, startPosY-6), (leftOffset+12, startPosY+6)), fill=YELLOW, outline=BLACK) - im_drawer.text(xy=(leftOffset+ 20, startPosY+TEXT_Y_DISPLACEMENT), + im_drawer.text(xy=(canvas.size[0] - xRightOffset - 170, startPosY+TEXT_Y_DISPLACEMENT), text='Frequency of the Peak LRS', font=smallLabelFont, fill=BLACK) @@ -1069,7 +1070,7 @@ class DisplayMappingResults(object): startPosY += stepPosY if self.additiveChecked: - startPosX = xLeftOffset + startPosX = canvas.size[0] - xRightOffset - 400 im_drawer.line( xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.ADDITIVE_COLOR_POSITIVE, width=2) @@ -1081,7 +1082,7 @@ class DisplayMappingResults(object): font=labelFont, fill=BLACK) if self.genotype.type == 'intercross' and self.dominanceChecked: - startPosX = xLeftOffset + startPosX = canvas.size[0] - xRightOffset - 400 startPosY += stepPosY im_drawer.line( xy=((startPosX, startPosY), (startPosX+17, startPosY)), @@ -1095,7 +1096,7 @@ class DisplayMappingResults(object): if self.haplotypeAnalystChecked: startPosY += stepPosY - startPosX = xLeftOffset + startPosX = canvas.size[0] - xRightOffset - 400 im_drawer.line( xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.HAPLOTYPE_POSITIVE, width=4) @@ -1114,7 +1115,10 @@ class DisplayMappingResults(object): if self.permChecked and self.nperm > 0: startPosY += stepPosY - startPosX = xLeftOffset + if self.bootChecked and not self.multipleInterval: + startPosX = canvas.size[0] - xRightOffset - 400 + else: + startPosX = canvas.size[0] - xRightOffset - 190 im_drawer.line( xy=((startPosX, startPosY), ( startPosX + 32, startPosY)), fill=self.SIGNIFICANT_COLOR, width=self.SIGNIFICANT_WIDTH) @@ -1123,10 +1127,10 @@ class DisplayMappingResults(object): fill=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH) im_drawer.text( text='Significant %s = %2.2f' % (self.LRS_LOD, self.significant), - xy=(xLeftOffset+42, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) + xy=(startPosX+42, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) im_drawer.text( text='Suggestive %s = %2.2f' % (self.LRS_LOD, self.suggestive), - xy=(xLeftOffset+42, startPosY + TEXT_Y_DISPLACEMENT +stepPosY), font=labelFont, + xy=(startPosX+42, startPosY + TEXT_Y_DISPLACEMENT +stepPosY), font=labelFont, fill=BLACK) labelFont = ImageFont.truetype(font=VERDANA_FILE, size=12*fontZoom) @@ -1197,22 +1201,26 @@ class DisplayMappingResults(object): im_drawer.textsize(string2, font=labelFont)[0]) im_drawer.text( text=identification, - xy=(canvas.size[0] - xRightOffset-d, 20*fontZoom), font=labelFont, + xy=(xLeftOffset, 20*fontZoom), font=labelFont, fill=labelColor) else: d = 4+ max( im_drawer.textsize(string1, font=labelFont)[0], im_drawer.textsize(string2, font=labelFont)[0]) im_drawer.text( - text=string1, xy=(canvas.size[0] - xRightOffset-d, 35*fontZoom), + text=string1, xy=(xLeftOffset, 35*fontZoom), font=labelFont, fill=labelColor) im_drawer.text( - text=string2, xy=(canvas.size[0] - xRightOffset-d, 50*fontZoom), + text=string2, xy=(xLeftOffset, 50*fontZoom), font=labelFont, fill=labelColor) if string3 != '': im_drawer.text( - text=string3, xy=(canvas.size[0] - xRightOffset-d, 65*fontZoom), + text=string3, xy=(xLeftOffset, 65*fontZoom), font=labelFont, fill=labelColor) + if string4 != '': + im_drawer.text( + text=string4, xy=(xLeftOffset, 80*fontZoom), + font=labelFont, fill=labelColor) def drawGeneBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): @@ -2244,6 +2252,7 @@ class DisplayMappingResults(object): ) sugg_coords = "%d, %d, %d, %d" % (start_pos_x, suggestiveY-2, rightEdge + 2*zoom, suggestiveY+2) sig_coords = "%d, %d, %d, %d" % (start_pos_x, significantY-2, rightEdge + 2*zoom, significantY+2) + if self.LRS_LOD == 'LRS': sugg_title = "Suggestive LRS = %0.2f" % self.suggestive sig_title = "Significant LRS = %0.2f" % self.significant -- cgit v1.2.3 From 295805eeb01aceb2651f79662c1462f06e1591cf Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 10 Dec 2020 12:27:48 -0600 Subject: Replacing the Scroller import with the CDN until we figure out why the new import doesn't work --- wqflask/wqflask/templates/show_trait.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index b02f8140..c95a0522 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -146,7 +146,7 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/scroller.dataTables.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/scroller/2.0.3/js/dataTables.scroller.min.js"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='nouislider/nouislider.js') }}"></script> <script type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script> <script type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script> -- cgit v1.2.3 From 4760b390f7e87ea16152a7ecf5422abfb4125176 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 15 Dec 2020 14:36:12 -0600 Subject: Fixed typo in mapping results table --- wqflask/wqflask/templates/mapping_results.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 86aa74b0..1a76ef7a 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -389,7 +389,7 @@ "orderable": false } ], "language": { - "info": "Showing1 from _START_ to _END_ of " + js_data.total_markers + " records", + "info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records", }, "order": [[1, "asc" ]], "sDom": "iRZtir", -- cgit v1.2.3 From 13ae2b093720a04b63f50a77b92e3b8e480b5ae1 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 15 Dec 2020 14:38:42 -0600 Subject: Added additive effect to GEMMA results + removed an unused function --- wqflask/wqflask/marker_regression/gemma_mapping.py | 46 ++++------------------ 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 61e4897c..630a3afa 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -80,7 +80,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco, maf os.system(generate_k_command) - gemma_command = GEMMA_WRAPPER_COMMAND + ' --json --input %s/gn2/%s.json -- ' % (TEMPDIR, k_output_filename) + GEMMAOPTS + ' -a %s/%s_snps.txt -lmm 2 -g %s/%s_geno.txt -p %s/gn2/%s.txt' % (flat_files('genotype/bimbam'), + gemma_command = GEMMA_WRAPPER_COMMAND + ' --json --input %s/gn2/%s.json -- ' % (TEMPDIR, k_output_filename) + GEMMAOPTS + ' -a %s/%s_snps.txt -lmm 9 -g %s/%s_geno.txt -p %s/gn2/%s.txt' % (flat_files('genotype/bimbam'), genofile_name, flat_files('genotype/bimbam'), genofile_name, @@ -101,7 +101,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco, maf marker_obs = parse_loco_output(this_dataset, gwa_output_filename) return marker_obs, gwa_output_filename else: - marker_obs = parse_loco_output(this_dataset, gwa_output_filename) + marker_obs = parse_loco_output(this_dataset, gwa_output_filename, use_loco) return marker_obs, gwa_output_filename def gen_pheno_txt_file(this_dataset, genofile_name, vals, trait_filename): @@ -145,41 +145,7 @@ def gen_covariates_file(this_dataset, covariates, samples): outfile.write(str(this_covariate[i]) + "\t") outfile.write("\n") -def parse_gemma_output(genofile_name): - included_markers = [] - p_values = [] - marker_obs = [] - - with open("{}{}_output.assoc.txt".format(webqtlConfig.GENERATED_IMAGE_DIR, genofile_name)) as output_file: - for line in output_file: - if line.startswith("chr\t"): - continue - else: - marker = {} - marker['name'] = line.split("\t")[1] - if line.split("\t")[0] != "X" and line.split("\t")[0] != "X/Y": - if "chr" in line.split("\t")[0]: - marker['chr'] = int(line.split("\t")[0][3:]) - else: - marker['chr'] = int(line.split("\t")[0]) - else: - marker['chr'] = line.split("\t")[0] - marker['Mb'] = float(line.split("\t")[2]) / 1000000 - marker['p_value'] = float(line.split("\t")[9]) - if math.isnan(marker['p_value']) or (marker['p_value'] <= 0): - marker['lod_score'] = 0 - #marker['lrs_value'] = 0 - else: - marker['lod_score'] = -math.log10(marker['p_value']) - #marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61 - marker_obs.append(marker) - - included_markers.append(line.split("\t")[1]) - p_values.append(float(line.split("\t")[9])) - - return marker_obs - -def parse_loco_output(this_dataset, gwa_output_filename): +def parse_loco_output(this_dataset, gwa_output_filename, loco="True"): output_filelist = [] with open("{}/gn2/".format(TEMPDIR) + gwa_output_filename + ".json") as data_file: @@ -218,7 +184,11 @@ 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")[9]) + if loco == "True": + marker['p_value'] = float(line.split("\t")[9]) + else: + marker['p_value'] = float(line.split("\t")[10]) + marker['additive'] = float(line.split("\t")[7]) if math.isnan(marker['p_value']) or (marker['p_value'] <= 0): marker['lod_score'] = 0 #marker['lrs_value'] = 0 -- cgit v1.2.3 From 87fdfc19009acda8b58729d0ffbdccbdf6a85a1e Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 16 Dec 2020 11:27:39 -0600 Subject: Set all attribute names to lower-case for sorting in order to keep order consistent --- wqflask/wqflask/show_trait/SampleList.py | 4 ++-- wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js | 2 +- wqflask/wqflask/static/new/javascript/show_trait.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 00495377..ece485ae 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -108,7 +108,7 @@ class SampleList(object): FROM CaseAttribute, CaseAttributeXRefNew WHERE CaseAttributeXRefNew.CaseAttributeId = CaseAttribute.Id AND CaseAttributeXRefNew.InbredSetId = %s - ORDER BY CaseAttribute.Name''', (str(self.dataset.group.id),)) + ORDER BY lower(CaseAttribute.Name)''', (str(self.dataset.group.id),)) self.attributes = {} for attr, values in itertools.groupby(results.fetchall(), lambda row: (row.Id, row.Name)): @@ -157,7 +157,7 @@ class SampleList(object): except ValueError: pass - attribute_values[self.attributes[item.Id].name] = attribute_value + attribute_values[self.attributes[item.Id].name.lower()] = attribute_value self.sample_attribute_values[sample_name] = attribute_values def get_first_attr_col(self): diff --git a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js index 5a4f151c..4362a75e 100644 --- a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js +++ b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js @@ -93,7 +93,7 @@ build_columns = function() { ); } - attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].name > js_data.attributes[b].name) ? 1 : -1) + attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].name.toLowerCase() > js_data.attributes[b].name.toLowerCase()) ? 1 : -1) for (i = 0; i < attr_keys.length; i++){ column_list.push( { diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 5dc9e456..98f90f7d 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -571,7 +571,7 @@ populate_sample_attributes_values_dropdown = function() { sample_attributes = []; var attributes_as_list = Object.keys(js_data.attributes).map(function(key) { - return [key, js_data.attributes[key].name]; + return [key, js_data.attributes[key].name.toLowerCase()]; }); attributes_as_list.sort(function(first, second) { -- cgit v1.2.3 From 124bc16cdc67b6ba31a281e619dcf15f181ba131 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 16 Dec 2020 11:33:10 -0600 Subject: Removed ID/Sample/Value from Show/Hide Columns in trait page and only show the option if columns other than those exist --- wqflask/wqflask/templates/show_trait_edit_data.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html index 4ad11a5e..0d34bebc 100644 --- a/wqflask/wqflask/templates/show_trait_edit_data.html +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -1,12 +1,9 @@ <div> {% for sample_type in sample_groups %} <div class="sample-table-container"> - {% if loop.index == 1 %} + {% if loop.index == 1 and (sample_groups[0].se_exists or has_num_cases or sample_groups[0].attributes|length > 0) %} <b>Show/Hide Columns:</b> <br> - <button class="toggle-vis" data-column="1">ID</button> - <button class="toggle-vis" data-column="2">Sample</button> - <button class="toggle-vis" data-column="3">Value</button> {% if sample_groups[0].se_exists %} <button class="toggle-vis" data-column="4,5">SE</button> {% if has_num_cases %} -- cgit v1.2.3 From ec1e37331e320ed674f184b738b9917753b6071f Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 16 Dec 2020 15:45:53 -0600 Subject: Made change to the way sample table width is calculated to account for sample name width --- wqflask/wqflask/show_trait/show_trait.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 0c6ae198..4c6dd005 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -186,8 +186,6 @@ class ShowTrait(object): self.has_num_cases = has_num_cases(self.this_trait) - self.stats_table_width, self.trait_table_width = get_table_widths(self.sample_groups, self.has_num_cases) - #ZS: Needed to know whether to display bar chart + get max sample name length in order to set table column width self.num_values = 0 self.binary = "true" #ZS: So it knows whether to display the Binary R/qtl mapping method, which doesn't work unless all values are 0 or 1 @@ -206,6 +204,8 @@ class ShowTrait(object): sample_column_width = max_samplename_width * 8 + self.stats_table_width, self.trait_table_width = get_table_widths(self.sample_groups, sample_column_width, self.has_num_cases) + if self.num_values >= 5000: self.maf = 0.01 else: @@ -547,12 +547,12 @@ def get_nearest_marker(this_trait, this_db): return result[0][0] -def get_table_widths(sample_groups, has_num_cases=False): +def get_table_widths(sample_groups, sample_column_width, has_num_cases=False): stats_table_width = 250 if len(sample_groups) > 1: stats_table_width = 450 - trait_table_width = 380 + trait_table_width = 300 + sample_column_width if sample_groups[0].se_exists: trait_table_width += 80 if has_num_cases: -- cgit v1.2.3 From fbec8e8bb919cb866d70db9f93a942f4554395fb Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 16 Dec 2020 15:53:59 -0600 Subject: Removed unused JS and fixed mapping covariate selection to work for both R/qtl and GEMMA --- wqflask/wqflask/static/new/javascript/show_trait.js | 10 +--------- wqflask/wqflask/templates/show_trait_mapping_tools.html | 8 ++++---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 98f90f7d..9cd79687 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -100,15 +100,7 @@ d3.select("#select_compare_trait").on("click", (function(_this) { return open_trait_selection(); }; })(this)); -d3.select("#select_covariates").on("click", (function(_this) { - return function() { - return open_covariate_selection(); - }; -})(this)); -$("#remove_covariates").click(function () { - $("input[name=covariates]").val("") - $(".selected-covariates").val("") -}); + $(".select_covariates").click(function () { open_covariate_selection(); }); diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index eca436c6..c42fe4aa 100755 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -74,8 +74,8 @@ No collections available. Please add traits to a collection to use them as covariates. {% else %} <div class="select-covar-div"> - <button type="button" id="select_covariates" class="btn btn-default select-covar-button">Select</button> - <button type="button" id="remove_covariates" class="btn btn-default select-covar-button">Remove</button> + <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button> + <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button> </div> <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea> {% endif %} @@ -317,8 +317,8 @@ No collections available. Please add traits to a collection to use them as covariates. {% else %} <div class="select-covar-div"> - <button type="button" id="select_covariates" class="btn btn-default select-covar-button">Select</button> - <button type="button" id="remove_covariates" class="btn btn-default select-covar-button">Remove</button> + <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button> + <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button> </div> <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea> {% endif %} -- cgit v1.2.3 From d080436fa5640522c45b1d8bb90e9ca20ba06d5d Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Thu, 17 Dec 2020 01:26:47 +0300 Subject: remove test for parse_gemma_output and modify run_gemma tests (#533) --- .../marker_regression/test_gemma_mapping.py | 32 ++-------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py index b8c13ab4..eab6afe6 100644 --- a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py +++ b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py @@ -5,7 +5,6 @@ from unittest import mock from wqflask.marker_regression.gemma_mapping import run_gemma from wqflask.marker_regression.gemma_mapping import gen_pheno_txt_file from wqflask.marker_regression.gemma_mapping import gen_covariates_file -from wqflask.marker_regression.gemma_mapping import parse_gemma_output from wqflask.marker_regression.gemma_mapping import parse_loco_output @@ -69,11 +68,9 @@ class TestGemmaMapping(unittest.TestCase): mock_parse_loco.return_value = [] results = run_gemma(this_trait=trait, this_dataset=dataset, samples=[ ], vals=[], covariates="", use_loco=True) - system_calls = [mock.call('ghc --json -- -debug -g /home/genotype/bimbam/file_geno.txt -p /home/user/data//gn2/trait1_dataset1_name_pheno.txt -a /home/genotype/bimbam/file_snps.txt -gk > /home/user/data//gn2/GP1_K_RRRRRR.json'), - mock.call('ghc --json --input /home/user/data//gn2/GP1_K_RRRRRR.json -- -debug -a /home/genotype/bimbam/file_snps.txt -lmm 2 -g /home/genotype/bimbam/file_geno.txt -p /home/user/data//gn2/trait1_dataset1_name_pheno.txt > /home/user/data//gn2/GP1_GWA_RRRRRR.json')] - mock_os.system.assert_has_calls(system_calls) + self.assertEqual(mock_os.system.call_count,2) mock_gen_pheno_txt.assert_called_once() - mock_parse_loco.assert_called_once_with(dataset, "GP1_GWA_RRRRRR") + mock_parse_loco.assert_called_once_with(dataset, "GP1_GWA_RRRRRR",True) mock_os.path.isfile.assert_called_once_with( ('/home/user/imgfile_output.assoc.txt')) self.assertEqual(mock_flat_files.call_count, 4) @@ -138,31 +135,6 @@ class TestGemmaMapping(unittest.TestCase): filehandler.write.assert_has_calls([mock.call( '-9\t'), mock.call('-9\t'), mock.call('-9\t'), mock.call('-9\t'), mock.call('\n')]) - @mock.patch("wqflask.marker_regression.gemma_mapping.webqtlConfig.GENERATED_IMAGE_DIR", "/home/user/img/") - def test_parse_gemma_output(self): - """add test for generating gemma output with obj returned""" - file = """X/Y\t gn2\t21\tQ\tE\tA\tP\tMMB\tCDE\t0.5 -X/Y\tgn2\t21322\tQ\tE\tA\tP\tMMB\tCDE\t0.5 -chr\tgn1\t12312\tQ\tE\tA\tP\tMMB\tCDE\t0.7 -X\tgn7\t2324424\tQ\tE\tA\tP\tMMB\tCDE\t0.4 -125\tgn9\t433575\tQ\tE\tA\tP\tMMB\tCDE\t0.67 -""" - with mock.patch("builtins.open", mock.mock_open(read_data=file)) as mock_open: - results = parse_gemma_output(genofile_name="gema_file") - expected = [{'name': ' gn2', 'chr': 'X/Y', 'Mb': 2.1e-05, 'p_value': 0.5, 'lod_score': 0.3010299956639812}, {'name': 'gn2', 'chr': 'X/Y', 'Mb': 0.021322, 'p_value': 0.5, 'lod_score': 0.3010299956639812}, - {'name': 'gn7', 'chr': 'X', 'Mb': 2.324424, 'p_value': 0.4, 'lod_score': 0.3979400086720376}, {'name': 'gn9', 'chr': 125, 'Mb': 0.433575, 'p_value': 0.67, 'lod_score': 0.17392519729917352}] - mock_open.assert_called_once_with( - "/home/user/img/gema_file_output.assoc.txt") - self.assertEqual(results, expected) - - @mock.patch("wqflask.marker_regression.gemma_mapping.webqtlConfig.GENERATED_IMAGE_DIR", "/home/user/img") - def test_parse_gemma_output_with_empty_return(self): - """add tests for parse gemma output where nothing returned""" - output_file_results = """chr\t today""" - with mock.patch("builtins.open", mock.mock_open(read_data=output_file_results)) as mock_open: - results = parse_gemma_output(genofile_name="gema_file") - self.assertEqual(results, []) - @mock.patch("wqflask.marker_regression.gemma_mapping.TEMPDIR", "/home/tmp") @mock.patch("wqflask.marker_regression.gemma_mapping.os") @mock.patch("wqflask.marker_regression.gemma_mapping.json") -- cgit v1.2.3 From e44f149fb6f6ca7d948c95f30faba4f4c2dc2ddd Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 17 Dec 2020 13:47:16 -0600 Subject: Correlation Min Expr and Location filters display depending upon the selected target dataset now, instead of the trait's dataset --- .../wqflask/static/new/javascript/show_trait.js | 18 ++++++++++++++++ .../show_trait_calculate_correlations.html | 24 ++++++++++++---------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 9cd79687..e9c7cce1 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -516,6 +516,24 @@ on_corr_method_change = function() { }; $('select[name=corr_type]').change(on_corr_method_change); +on_dataset_change = function() { + let dataset_type = $('select[name=corr_dataset] option:selected').data('type'); + + if (dataset_type == "mrna_assay"){ + $('#min_expr_filter').show(); + $('#location_filter').show(); + } + else if (dataset_type == "pheno"){ + $('#min_expr_filter').show(); + $('#location_filter').hide(); + } + else { + $('#min_expr_filter').hide(); + $('#location_filter').show(); + } +} +$('select[name=corr_dataset]').change(on_dataset_change); + submit_special = function(url) { get_table_contents_for_form_submit("trait_data_form"); $("#trait_data_form").attr("action", url); diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index ba72ff27..12294efb 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -19,18 +19,18 @@ <select name="corr_dataset" class="form-control"> {% for tissue in corr_tools.dataset_menu %} {% if tissue.tissue %} - <optgroup label="{{ tissue.tissue }} ------"> + <optgroup label="{{ tissue.tissue }} ------"> {% endif %} {% for dataset in tissue.datasets %} - <option value="{{ dataset[1] }}" - {% if corr_tools.dataset_menu_selected == dataset[1] %} - selected - {% endif %}> - {{ dataset[0] }} - </option> + <option data-type="{% if tissue.tissue %}mrna_assay{% elif dataset[1][-4:] == 'Geno' %}geno{% else %}pheno{% endif %}" value="{{ dataset[1] }}" + {% if corr_tools.dataset_menu_selected == dataset[1] %} + selected + {% endif %}> + {{ dataset[0] }} + </option> {% endfor %} {% if tissue.tissue %} - </optgroup> + </optgroup> {% endif %} {% endfor %} </select> @@ -74,14 +74,16 @@ </select> </div> </div> - {% if dataset.type != "Publish" %} - <div class="form-group"> + {% if dataset.type != "Geno" %} + <div id="min_expr_filter" class="form-group"> <label class="col-xs-2 control-label">Min Expr</label> <div class="col-xs-4 controls"> <input name="min_expr" value="" type="text" class="form-control min-expr-field"> </div> </div> - <div class="form-group"> + {% endif %} + {% if dataset.type != "Pheno" %} + <div id="location_filter" class="form-group"> <label class="col-xs-2 control-label">Location</label> <div class="col-xs-6 controls"> <span> -- cgit v1.2.3 From 561dfe5e1dedbf9c31d45023b895a2b9bb003869 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 17 Dec 2020 13:51:59 -0600 Subject: Replaced Pheno with Publish for identifying dataset type in corr options --- wqflask/wqflask/templates/show_trait_calculate_correlations.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index 12294efb..6f124943 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -82,7 +82,7 @@ </div> </div> {% endif %} - {% if dataset.type != "Pheno" %} + {% if dataset.type != "Publish" %} <div id="location_filter" class="form-group"> <label class="col-xs-2 control-label">Location</label> <div class="col-xs-6 controls"> -- cgit v1.2.3 From f851ea02b94b98f1537060a7189e25086fc991e9 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 17 Dec 2020 14:48:55 -0600 Subject: Fixed a couple logic issues and changed indentation in show_trait_calculate_correlations.html --- .../show_trait_calculate_correlations.html | 154 ++++++++++----------- 1 file changed, 75 insertions(+), 79 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index 6f124943..eaa0c308 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -2,88 +2,85 @@ <div class="col-xs-3 correlation-options"> <div class="form-horizontal section-form-div"> - <div class="form-group"> - <label for="corr_type" class="col-xs-2 control-label">Method</label> - <div class="col-xs-3 controls"> - <select name="corr_type" class="form-control"> - <option value="sample">Sample r</option> - <option value="lit">Literature r</option> - <option value="tissue">Tissue r</option> - </select> - </div> - </div> + <div class="form-group"> + <label for="corr_type" class="col-xs-2 control-label">Method</label> + <div class="col-xs-3 controls"> + <select name="corr_type" class="form-control"> + <option value="sample">Sample r</option> + <option value="lit">Literature r</option> + <option value="tissue">Tissue r</option> + </select> + </div> + </div> - <div class="form-group"> - <label for="corr_dataset" class="col-xs-2 control-label">Database</label> - <div class="col-xs-10 controls"> - <select name="corr_dataset" class="form-control"> - {% for tissue in corr_tools.dataset_menu %} - {% if tissue.tissue %} - <optgroup label="{{ tissue.tissue }} ------"> - {% endif %} - {% for dataset in tissue.datasets %} - <option data-type="{% if tissue.tissue %}mrna_assay{% elif dataset[1][-4:] == 'Geno' %}geno{% else %}pheno{% endif %}" value="{{ dataset[1] }}" - {% if corr_tools.dataset_menu_selected == dataset[1] %} - selected - {% endif %}> - {{ dataset[0] }} - </option> - {% endfor %} - {% if tissue.tissue %} - </optgroup> - {% endif %} - {% endfor %} - </select> - </div> - </div> + <div class="form-group"> + <label for="corr_dataset" class="col-xs-2 control-label">Database</label> + <div class="col-xs-10 controls"> + <select name="corr_dataset" class="form-control"> + {% for tissue in corr_tools.dataset_menu %} + {% if tissue.tissue %} + <optgroup label="{{ tissue.tissue }} ------"> + {% endif %} + {% for dataset in tissue.datasets %} + <option data-type="{% if tissue.tissue %}mrna_assay{% elif dataset[1][-4:] == 'Geno' %}geno{% else %}pheno{% endif %}" value="{{ dataset[1] }}" + {% if corr_tools.dataset_menu_selected == dataset[1] %} + selected + {% endif %}> + {{ dataset[0] }} + </option> + {% endfor %} + {% if tissue.tissue %} + </optgroup> + {% endif %} + {% endfor %} + </select> + </div> + </div> - <div class="form-group"> - <label for="corr_return_results" class="col-xs-2 control-label">Limit to</label> - <div class="col-xs-4 controls"> - <select name="corr_return_results" class="form-control"> - {% for return_result in corr_tools.return_results_menu %} - <option value="{{ return_result }}" - {% if corr_tools.return_results_menu_selected == return_result %} - selected - {% endif %}> - Top {{ return_result }} - </option> - {% endfor %} - </select> - </div> - </div> + <div class="form-group"> + <label for="corr_return_results" class="col-xs-2 control-label">Limit to</label> + <div class="col-xs-4 controls"> + <select name="corr_return_results" class="form-control"> + {% for return_result in corr_tools.return_results_menu %} + <option value="{{ return_result }}" + {% if corr_tools.return_results_menu_selected == return_result %} + selected + {% endif %}> + Top {{ return_result }} + </option> + {% endfor %} + </select> + </div> + </div> - <div class="form-group"> - <label for="corr_samples_group" class="col-xs-2 control-label">Samples</label> - <div class="col-xs-4 controls"> - <select name="corr_samples_group" class="form-control"> - {% for group, pretty_group in sample_group_types.items() %} - <option value="{{ group }}">{{ pretty_group }}</option> - {% endfor %} - </select> - </div> - </div> + <div class="form-group"> + <label for="corr_samples_group" class="col-xs-2 control-label">Samples</label> + <div class="col-xs-4 controls"> + <select name="corr_samples_group" class="form-control"> + {% for group, pretty_group in sample_group_types.items() %} + <option value="{{ group }}">{{ pretty_group }}</option> + {% endfor %} + </select> + </div> + </div> - <div id="corr_sample_method" class="form-group"> - <label for="corr_sample_method" class="col-xs-2 control-label">Type</label> - <div class="col-xs-4 controls"> - <select name="corr_sample_method" class="form-control"> - <option value="pearson">Pearson</option> - <option value="spearman">Spearman Rank</option> - <option value="bicor">Biweight Midcorrelation</option> - </select> - </div> - </div> - {% if dataset.type != "Geno" %} - <div id="min_expr_filter" class="form-group"> - <label class="col-xs-2 control-label">Min Expr</label> - <div class="col-xs-4 controls"> - <input name="min_expr" value="" type="text" class="form-control min-expr-field"> - </div> - </div> - {% endif %} - {% if dataset.type != "Publish" %} - <div id="location_filter" class="form-group"> + <div id="corr_sample_method" class="form-group"> + <label for="corr_sample_method" class="col-xs-2 control-label">Type</label> + <div class="col-xs-4 controls"> + <select name="corr_sample_method" class="form-control"> + <option value="pearson">Pearson</option> + <option value="spearman">Spearman Rank</option> + <option value="bicor">Biweight Midcorrelation</option> + </select> + </div> + </div> + <div id="min_expr_filter" class="form-group" style="display: {% if dataset.type != 'Geno' %}block{% else %}none{% endif %};"> + <label class="col-xs-2 control-label">Min Expr</label> + <div class="col-xs-4 controls"> + <input name="min_expr" value="" type="text" class="form-control min-expr-field"> + </div> + </div> + <div id="location_filter" class="form-group" style="display: {% if dataset.type != 'Publish' %}block{% else %}none{% endif %};"> <label class="col-xs-2 control-label">Location</label> <div class="col-xs-6 controls"> <span> @@ -93,7 +90,6 @@ <br> </div> </div> - {% endif %} <div class="form-group"> <label class="col-xs-2 control-label">Range</label> <div class="col-xs-5 controls"> -- cgit v1.2.3 From be1c1c1c48d75875f03b7ff4e91654f390571b58 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 17 Dec 2020 14:49:26 -0600 Subject: Added Mean (mean expression) column to phenotype correlation results table --- wqflask/wqflask/templates/correlation_page.html | 26 +++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index 8e2a23fd..6188c0e7 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -95,14 +95,15 @@ {% elif target_dataset.type == 'Publish' %} <button class="toggle-vis" data-column="3">Abbreviation</button> <button class="toggle-vis" data-column="4">Description</button> - <button class="toggle-vis" data-column="5">Authors</button> - <button class="toggle-vis" data-column="6">Year</button> - <button class="toggle-vis" data-column="7">Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}</button> - <button class="toggle-vis" data-column="8">N</button> - <button class="toggle-vis" data-column="9">Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})</button> - <button class="toggle-vis" data-column="10">Peak LOD</button> - <button class="toggle-vis" data-column="11">Peak Location</button> - <button class="toggle-vis" data-column="12">Effect Size</button> + <button class="toggle-vis" data-column="5">Mean</button> + <button class="toggle-vis" data-column="6">Authors</button> + <button class="toggle-vis" data-column="7">Year</button> + <button class="toggle-vis" data-column="8">Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}</button> + <button class="toggle-vis" data-column="9">N</button> + <button class="toggle-vis" data-column="10">Sample p({% if corr_method == 'pearson' %}r{% else %}rho{% endif %})</button> + <button class="toggle-vis" data-column="11">Peak LOD</button> + <button class="toggle-vis" data-column="12">Peak Location</button> + <button class="toggle-vis" data-column="13">Effect Size</button> {% else %} <button class="toggle-vis" data-column="3">Location</button> <button class="toggle-vis" data-column="4">Sample {% if corr_method == 'pearson' %}r{% else %}rho{% endif %}</button> @@ -398,6 +399,13 @@ } } }, + { + 'title': "Mean", + 'type': "natural-minus-na", + 'width': "40px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, { 'title': "Authors", 'type': "natural", @@ -514,6 +522,8 @@ } ], {% if target_dataset.type == 'Geno' %} "order": [[6, "asc" ]], + {% elif target_dataset.type == 'Publish' %} + "order": [[10, "asc" ]], {% else %} "order": [[9, "asc" ]], {% endif %} -- cgit v1.2.3 From 03de3751bd003117dce2bc4bf085092bd8f9a0fe Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 17 Dec 2020 14:50:34 -0600 Subject: Fixed some logic to work correctly with the changes to the way correlation filters work + changed correlation python code to include Mean (mean expression) for phenotype results --- wqflask/wqflask/correlation/show_corr_results.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 7d3b9b9f..298a3559 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -71,7 +71,6 @@ class CorrelationResults(object): assert('corr_sample_method' in start_vars) assert('corr_samples_group' in start_vars) assert('corr_dataset' in start_vars) - #assert('min_expr' in start_vars) assert('corr_return_results' in start_vars) if 'loc_chr' in start_vars: assert('min_loc_mb' in start_vars) @@ -197,15 +196,15 @@ class CorrelationResults(object): if (float(self.correlation_data[trait][0]) >= self.p_range_lower and float(self.correlation_data[trait][0]) <= self.p_range_upper): - if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": - + if (self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Publish") and bool(trait_object.mean): if (self.min_expr != None) and (float(trait_object.mean) < self.min_expr): continue - elif range_chr_as_int != None and (chr_as_int != range_chr_as_int): + if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": + if range_chr_as_int != None and (chr_as_int != range_chr_as_int): continue - elif (self.min_location_mb != None) and (float(trait_object.mb) < float(self.min_location_mb)): + if (self.min_location_mb != None) and (float(trait_object.mb) < float(self.min_location_mb)): continue - elif (self.max_location_mb != None) and (float(trait_object.mb) > float(self.max_location_mb)): + if (self.max_location_mb != None) and (float(trait_object.mb) > float(self.max_location_mb)): continue (trait_object.sample_r, @@ -519,6 +518,7 @@ def generate_corr_json(corr_results, this_trait, dataset, target_dataset, for_ap elif target_dataset.type == "Publish": results_dict['abbreviation_display'] = "N/A" results_dict['description'] = "N/A" + results_dict['mean'] = "N/A" results_dict['authors_display'] = "N/A" results_dict['additive'] = "N/A" if for_api: @@ -532,6 +532,8 @@ def generate_corr_json(corr_results, this_trait, dataset, target_dataset, for_ap results_dict['abbreviation_display'] = trait.abbreviation if bool(trait.description_display): results_dict['description'] = trait.description_display + if bool(trait.mean): + results_dict['mean'] = f"{float(trait.mean):.3f}" if bool(trait.authors): authors_list = trait.authors.split(',') if len(authors_list) > 6: @@ -605,6 +607,7 @@ def get_header_fields(data_type, corr_method): 'Record', 'Abbreviation', 'Description', + 'Mean', 'Authors', 'Year', 'Sample rho', @@ -618,6 +621,7 @@ def get_header_fields(data_type, corr_method): 'Record', 'Abbreviation', 'Description', + 'Mean', 'Authors', 'Year', 'Sample r', -- cgit v1.2.3 From 47c15cdbd8d54afca05bf939dec8d7d461cff5a5 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:30:13 -0600 Subject: Added function that fetches sample data and converts it to JSON to show_trait.js --- .../wqflask/static/new/javascript/show_trait.js | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 98f90f7d..b71a9dd8 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -427,6 +427,25 @@ process_id = function() { } return processed; }; + +fetch_sample_values = function() { + // This is meant to fetch all sample values using DataTables API, since they can't all be submitted with the form when using Scroller (and this should also be faster) + sample_val_dict = {}; + + table = 'samples_primary'; + if ($('#' + table).length){ + table_api = $('#' + table).DataTable(); + val_nodes = table_api.column(3).nodes().to$(); + for (_j = 0; _j < val_nodes.length; _j++){ + sample_name = val_nodes[_j].childNodes[0].name.split(":")[1] + sample_val = val_nodes[_j].childNodes[0].value + sample_val_dict[sample_name] = sample_val + } + } + + return sample_val_dict; +} + edit_data_change = function() { var already_seen, checkbox, name, real_dict, real_value, real_variance, row, rows, sample_sets, table, tables, _i, _j, _len, _len1; already_seen = {}; @@ -525,7 +544,7 @@ on_corr_method_change = function() { $('select[name=corr_type]').change(on_corr_method_change); submit_special = function(url) { - get_table_contents_for_form_submit("trait_data_form"); + $("input[name=sample_vals]").val(JSON.stringify(fetch_sample_values())) $("#trait_data_form").attr("action", url); $("#trait_data_form").submit(); }; @@ -549,7 +568,7 @@ get_table_contents_for_form_submit = function(form_id) { }); } -var corr_input_list = ['corr_type', 'primary_samples', 'trait_id', 'dataset', 'group', 'tool_used', 'form_url', 'corr_sample_method', 'corr_samples_group', 'corr_dataset', 'min_expr', +var corr_input_list = ['sample_vals', 'corr_type', 'primary_samples', 'trait_id', 'dataset', 'group', 'tool_used', 'form_url', 'corr_sample_method', 'corr_samples_group', 'corr_dataset', 'min_expr', 'corr_return_results', 'loc_chr', 'min_loc_mb', 'max_loc_mb', 'p_range_lower', 'p_range_upper'] $(".corr_compute").on("click", (function(_this) { -- cgit v1.2.3 From 66b8f70f162f2d6356c6e9af5066c5b90335f7c2 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:33:04 -0600 Subject: Changed views.py to accept sample data for loading page and mapping as JSON instead of having separate form parameters for each sample + removed some commented out code/logging --- wqflask/wqflask/views.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 25563e86..c136711e 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -621,12 +621,13 @@ def loading_page(): wanted = initial_start_vars['wanted_inputs'].split(",") start_vars = {} for key, value in list(initial_start_vars.items()): - if key in wanted or key.startswith(('value:')): + if key in wanted: start_vars[key] = value if 'n_samples' in start_vars: n_samples = int(start_vars['n_samples']) else: + sample_vals_dict = json.loads(start_vars['sample_vals']) if 'group' in start_vars: dataset = create_dataset(start_vars['dataset'], group_name = start_vars['group']) else: @@ -642,8 +643,7 @@ def loading_page(): samples = genofile_samples for sample in samples: - value = start_vars.get('value:' + sample) - if value != "x": + if sample_vals_dict[sample] != "x": n_samples += 1 start_vars['n_samples'] = n_samples @@ -660,7 +660,6 @@ def loading_page(): @app.route("/run_mapping", methods=('POST',)) def mapping_results_page(): initial_start_vars = request.form - #logger.debug("Mapping called with initial_start_vars:", initial_start_vars.items()) logger.info(request.url) temp_uuid = initial_start_vars['temp_uuid'] wanted = ( @@ -670,6 +669,7 @@ def mapping_results_page(): 'species', 'samples', 'vals', + 'sample_vals', 'first_run', 'output_files', 'geno_db_exists', @@ -723,13 +723,11 @@ def mapping_results_page(): ) start_vars = {} for key, value in list(initial_start_vars.items()): - if key in wanted or key.startswith(('value:')): + if key in wanted: start_vars[key] = value - #logger.debug("Mapping called with start_vars:", start_vars) version = "v3" key = "mapping_results:{}:".format(version) + json.dumps(start_vars, sort_keys=True) - #logger.info("key is:", pf(key)) with Bench("Loading cache"): result = None # Just for testing #result = Redis.get(key) @@ -775,10 +773,6 @@ def mapping_results_page(): rendered_template = render_template("pair_scan_results.html", **result) else: gn1_template_vars = display_mapping_results.DisplayMappingResults(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) with Bench("Rendering template"): #if (gn1_template_vars['mapping_method'] == "gemma") or (gn1_template_vars['mapping_method'] == "plink"): -- cgit v1.2.3 From 20314199985aa21a00a47f3c7b053ec49bc8b60d Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:33:44 -0600 Subject: Added sample_vals input element that is meant to contain JSON for all sample values (pulled from the sample table using DataTables API in show_trait.js) --- wqflask/wqflask/templates/show_trait.html | 1 + 1 file changed, 1 insertion(+) diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index c881eb76..77fc9342 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -35,6 +35,7 @@ <input type="hidden" name="genofile" value=""> <input type="hidden" name="covariates" value=""> <input type="hidden" name="transform" value=""> + <input type="hidden" name="sample_vals" value=""> <div class="container showtrait-main-div"> <div class="panel-group" id="accordion"> -- cgit v1.2.3 From 969a421efc0bd4529607fdc14332acd897d8e106 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:34:21 -0600 Subject: Added sample_vals to the list of mapping inputs that determines what is included in start_vars when trait page parameters are passed to the mapping loading page --- wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 34582f21..3ae52975 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -141,7 +141,7 @@ $('input[name=display_all]').change((function(_this) { })(this)); //ZS: This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping -var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', +var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', 'sample_vals', 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results', 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker', 'control_marker_db', 'do_control', 'genofile', 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck', -- cgit v1.2.3 From 95d1887bba6b93ea310c226cb82e9cb64f75cc67 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:35:09 -0600 Subject: Changed mapping_results.html to have a single sample_vals input instead of separate ones for every sample + added sample_vals to the list of inputs sent to the loading page --- wqflask/wqflask/templates/mapping_results.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 1a76ef7a..2fb37832 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -31,10 +31,7 @@ {% endif %} <input type="hidden" name="results_path" value="{{ mapping_results_path }}"> <input type="hidden" name="method" value="{{ mapping_method }}"> - <input type="hidden" name="samples" value="{{ samples|join(",") }}"> - {% for sample in samples %} - <input type="hidden" name="value:{{ sample }}" value="{{ vals[loop.index - 1] }}"> - {% endfor %} + <input type="hidden" name="sample_vals" value="{{ sample_vals }}"> <input type="hidden" name="n_samples" value="{{ n_samples }}"> <input type="hidden" name="maf" value="{{ maf }}"> <input type="hidden" name="use_loco" value="{{ use_loco }}"> @@ -450,7 +447,7 @@ }); - var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', + var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale', 'sample_vals', 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars', 'num_bootstrap', 'bootCheck', 'bootstrap_results', 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'color_scheme', 'manhattan_single_color', 'control_marker', 'control_marker_db', 'do_control', 'genofile', 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck', -- cgit v1.2.3 From 7544d03a6d819d70779deb79d38b7465a648c1ff Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:36:53 -0600 Subject: Changed run_mapping.py to get sample names and values from JSON instead of a bunch of separate input parameters --- wqflask/wqflask/marker_regression/run_mapping.py | 64 ++++++------------------ 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 891fcc66..a1f87b61 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -71,56 +71,22 @@ class RunMapping(object): all_samples_ordered = self.dataset.group.all_samples_ordered() self.vals = [] - if 'samples' in start_vars: - self.samples = start_vars['samples'].split(",") - if (len(genofile_samplelist) != 0): - for sample in genofile_samplelist: - if sample in self.samples: - value = start_vars.get('value:' + sample) - if value: - self.vals.append(value) - else: - self.vals.append("x") - else: - for sample in self.samples: - value = start_vars.get('value:' + sample) - if value: - self.vals.append(value) + self.samples = [] + self.sample_vals = start_vars['sample_vals'] + sample_val_dict = json.loads(self.sample_vals) + samples = sample_val_dict.keys() + if (len(genofile_samplelist) != 0): + for sample in genofile_samplelist: + self.samples.append(sample) + if sample in samples: + self.vals.append(sample_val_dict[sample]) + else: + self.vals.append("x") else: - self.samples = [] - if (len(genofile_samplelist) != 0): - for sample in genofile_samplelist: - if sample in self.dataset.group.samplelist: - in_trait_data = False - for item in self.this_trait.data: - if self.this_trait.data[item].name == sample: - value = start_vars['value:' + self.this_trait.data[item].name] - self.samples.append(self.this_trait.data[item].name) - self.vals.append(value) - in_trait_data = True - break - if not in_trait_data: - value = start_vars.get('value:' + sample) - if value: - self.samples.append(sample) - self.vals.append(value) - else: - self.vals.append("x") - else: - for sample in self.dataset.group.samplelist: # sample is actually the name of an individual - in_trait_data = False - for item in self.this_trait.data: - if self.this_trait.data[item].name == sample: - value = start_vars['value:' + self.this_trait.data[item].name] - self.samples.append(self.this_trait.data[item].name) - self.vals.append(value) - in_trait_data = True - break - if not in_trait_data: - value = start_vars.get('value:' + sample) - if value: - self.samples.append(sample) - self.vals.append(value) + for sample in self.dataset.group.samplelist: + if sample in samples: + self.vals.append(sample_val_dict[sample]) + self.samples.append(sample) if 'n_samples' in start_vars: self.n_samples = start_vars['n_samples'] -- cgit v1.2.3 From 6d493f7ef57322f226dd310497e4dc7518440cfd Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:38:09 -0600 Subject: Changed display_mapping_results.py to get sample names and values from the JSON sample_vals parameter --- .../marker_regression/display_mapping_results.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 08c2d750..9f1b050d 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -270,8 +270,9 @@ class DisplayMappingResults(object): # Needing for form submission when doing single chr # mapping or remapping after changing options - self.samples = start_vars['samples'] - self.vals = start_vars['vals'] + self.sample_vals = start_vars['sample_vals'] + self.sample_vals_dict = json.loads(self.sample_vals) + self.transform = start_vars['transform'] self.mapping_method = start_vars['mapping_method'] self.mapping_results_path = start_vars['mapping_results_path'] @@ -492,11 +493,10 @@ class DisplayMappingResults(object): ## count the amount of individuals to be plotted, and increase self.graphHeight if self.haplotypeAnalystChecked and self.selectedChr > -1: thisTrait = self.this_trait - _strains, _vals, _vars, _aliases = thisTrait.export_informative() smd=[] - for ii, _val in enumerate(self.vals): - if _val != "x": - temp = GeneralObject(name=self.samples[ii], value=float(_val)) + for sample in self.sample_vals_dict.keys(): + if self.sample_vals_dict[sample] != "x": + temp = GeneralObject(name=sample, value=float(self.sample_vals_dict[sample])) smd.append(temp) else: continue @@ -1464,12 +1464,11 @@ class DisplayMappingResults(object): yPaddingTop = yTopOffset thisTrait = self.this_trait - _strains, _vals, _vars, _aliases = thisTrait.export_informative() smd=[] - for ii, _val in enumerate(self.vals): - if _val != "x": - temp = GeneralObject(name=self.samples[ii], value=float(_val)) + for sample in self.sample_vals_dict.keys(): + if self.sample_vals_dict[sample] != "x": + temp = GeneralObject(name=sample, value=float(self.sample_vals_dict[sample])) smd.append(temp) else: continue -- cgit v1.2.3 From 41efd6840f2e1c052dbb77affd6f09fc2e2bcd05 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:39:31 -0600 Subject: Changed show_corr_results.py to get sample names/values from the JSON sample_vals parameter --- wqflask/wqflask/correlation/show_corr_results.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 7d3b9b9f..be983c87 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -87,8 +87,6 @@ class CorrelationResults(object): else: helper_functions.get_species_dataset_trait(self, start_vars) - #self.dataset.group.read_genotype_file() - corr_samples_group = start_vars['corr_samples_group'] self.sample_data = {} @@ -454,13 +452,13 @@ class CorrelationResults(object): if not excluded_samples: excluded_samples = () + sample_val_dict = json.loads(start_vars['sample_vals']) for sample in sample_names: if sample not in excluded_samples: - # print("Looking for",sample,"in",start_vars) - value = start_vars.get('value:' + sample) - if value: - if not value.strip().lower() == 'x': - self.sample_data[str(sample)] = float(value) + value = sample_val_dict[sample] + if not value.strip().lower() == 'x': + self.sample_data[str(sample)] = float(value) + def do_bicor(this_trait_vals, target_trait_vals): r_library = ro.r["library"] # Map the library function -- cgit v1.2.3 From 453ac34383d54910e821609b80b69ff41c48d0ce Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 14:53:01 -0600 Subject: Added Additive Effect when using LOCO with GEMMA --- wqflask/wqflask/marker_regression/gemma_mapping.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index 630a3afa..ab3a7278 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -54,7 +54,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco, maf TEMPDIR, trait_filename) if covariates != "": - gemma_command += ' -c %s/%s_covariates.txt -a %s/%s_snps.txt -lmm 2 -maf %s > %s/gn2/%s.json' % (flat_files('mapping'), + gemma_command += ' -c %s/%s_covariates.txt -a %s/%s_snps.txt -lmm 9 -maf %s > %s/gn2/%s.json' % (flat_files('mapping'), this_dataset.group.name, flat_files('genotype/bimbam'), genofile_name, @@ -62,7 +62,7 @@ def run_gemma(this_trait, this_dataset, samples, vals, covariates, use_loco, maf TEMPDIR, gwa_output_filename) else: - gemma_command += ' -a %s/%s_snps.txt -lmm 2 -maf %s > %s/gn2/%s.json' % (flat_files('genotype/bimbam'), + gemma_command += ' -a %s/%s_snps.txt -lmm 9 -maf %s > %s/gn2/%s.json' % (flat_files('genotype/bimbam'), genofile_name, maf, TEMPDIR, @@ -184,11 +184,8 @@ def parse_loco_output(this_dataset, gwa_output_filename, loco="True"): else: marker['chr'] = line.split("\t")[0] marker['Mb'] = float(line.split("\t")[2]) / 1000000 - if loco == "True": - marker['p_value'] = float(line.split("\t")[9]) - else: - marker['p_value'] = float(line.split("\t")[10]) - marker['additive'] = float(line.split("\t")[7]) + marker['p_value'] = float(line.split("\t")[10]) + marker['additive'] = float(line.split("\t")[7]) if math.isnan(marker['p_value']) or (marker['p_value'] <= 0): marker['lod_score'] = 0 #marker['lrs_value'] = 0 -- cgit v1.2.3 From 69f92ef2bc10477a80eff96fb7cc83fee11f31e8 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 17:05:55 -0600 Subject: This should fix the Github login error --- wqflask/wqflask/user_login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index f25ebc32..b6266b2a 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -239,7 +239,7 @@ def github_oauth2(): } result = requests.post("https://github.com/login/oauth/access_token", json=data) - result_dict = {arr[0]:arr[1] for arr in [tok.split("=") for tok in [token.encode("utf-8") for token in result.text.split("&")]]} + result_dict = {arr[0]:arr[1] for arr in [tok.split("=") for tok in result.text.split("&")]} github_user = get_github_user_details(result_dict["access_token"]) -- cgit v1.2.3 From fc717c36d334f364bbae8c98f31ddf78e18d64e3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 17:34:47 -0600 Subject: Added redirect_uri to the ORCID_AUTH_URL since it wasn't working due to missing this parameter --- wqflask/utility/tools.py | 2 +- wqflask/wqflask/user_login.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 68ef0f04..65df59c3 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -267,7 +267,7 @@ ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = None if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: ORCID_AUTH_URL = "https://orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \ - ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + "&redirect_uri=" + GN2_BRANCH_URL + "n/login/orcid_oauth2" ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index b6266b2a..bc608e84 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -25,7 +25,7 @@ from utility.logger import getLogger logger = getLogger(__name__) from smtplib import SMTP -from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD, LOG_SQL_ALCHEMY +from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD, LOG_SQL_ALCHEMY, GN2_BRANCH_URL THREE_DAYS = 60 * 60 * 24 * 3 @@ -277,9 +277,11 @@ def orcid_oauth2(): data = { "client_id": ORCID_CLIENT_ID, "client_secret": ORCID_CLIENT_SECRET, - "grant_type": "authorization_code", + "grant_type": "authorization_code", + "redirect_uri": GN2_BRANCH_URL + "n/login/orcid_oauth2", "code": code } + result = requests.post(ORCID_TOKEN_URL, data=data) result_dict = json.loads(result.text.encode("utf-8")) -- cgit v1.2.3 From 0560b297a9a6139079ee237bc8d98f471e7703f5 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 25 Dec 2020 19:18:48 -0600 Subject: Added edit_data_change to block_by_attribute_value so it will update stats figures after using that tool --- wqflask/wqflask/static/new/javascript/show_trait.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index e9c7cce1..312cc22f 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -641,6 +641,8 @@ block_by_attribute_value = function() { this_val_node.value = "x"; } } + + edit_data_change(); }; $('#exclude_by_attr').click(block_by_attribute_value); -- cgit v1.2.3 From c26304ed6a2937654794f908c13ccd3ba4a66453 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Dec 2020 14:25:51 -0600 Subject: Fix issue that caused error bars to not work for bar chart --- wqflask/wqflask/static/new/javascript/show_trait.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 312cc22f..6918cf34 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -448,7 +448,7 @@ edit_data_change = function() { if (is_number(sample_val) && sample_val !== "") { sample_val = parseFloat(sample_val); sample_sets[table].add_value(sample_val); - if (typeof var_nodes !== 'undefined'){ + if (typeof var_nodes === 'undefined'){ sample_var = null; } else { sample_var = var_nodes[_j].childNodes[0].value @@ -471,6 +471,7 @@ edit_data_change = function() { } } } + } update_stat_values(sample_sets); -- cgit v1.2.3 From 3241a8de759f18bbbc73bd755419831db37e71a0 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Dec 2020 15:01:31 -0600 Subject: Added 'Location Type' option to show_trait correlation options --- wqflask/wqflask/templates/show_trait_calculate_correlations.html | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index eaa0c308..46232b97 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -80,6 +80,15 @@ <input name="min_expr" value="" type="text" class="form-control min-expr-field"> </div> </div> + <div class="form-group"> + <label for="location_type" class="col-xs-2 control-label">Location Type</label> + <div class="col-xs-4 controls"> + <select name="location_type" class="form-control"> + {% if dataset.type != 'Publish' %}<option value="gene">Gene</option>{% endif %} + <option value="highest_lod">Highest LOD</option> + </select> + </div> + </div> <div id="location_filter" class="form-group" style="display: {% if dataset.type != 'Publish' %}block{% else %}none{% endif %};"> <label class="col-xs-2 control-label">Location</label> <div class="col-xs-6 controls"> -- cgit v1.2.3 From ab9aebc567d1a10282ae55f282993a3fa9dd3582 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Dec 2020 15:14:32 -0600 Subject: Changed correlation options to always show the location field and both location_type options, since one or the other will always apply --- wqflask/wqflask/templates/show_trait_calculate_correlations.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index 46232b97..cba977ac 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -84,12 +84,12 @@ <label for="location_type" class="col-xs-2 control-label">Location Type</label> <div class="col-xs-4 controls"> <select name="location_type" class="form-control"> - {% if dataset.type != 'Publish' %}<option value="gene">Gene</option>{% endif %} + <option value="gene" {% if dataset.type == 'Publish' %}disabled{% endif %}>Gene</option> <option value="highest_lod">Highest LOD</option> </select> </div> </div> - <div id="location_filter" class="form-group" style="display: {% if dataset.type != 'Publish' %}block{% else %}none{% endif %};"> + <div id="location_filter" class="form-group"> <label class="col-xs-2 control-label">Location</label> <div class="col-xs-6 controls"> <span> -- cgit v1.2.3 From a336ca94fd473fdfd6cc5a83ce879429c0f1db92 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Dec 2020 15:15:01 -0600 Subject: Added JS controlling which location_type options are available depending upon the selected target dataset --- wqflask/wqflask/static/new/javascript/show_trait.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 6918cf34..a301615b 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -519,21 +519,26 @@ $('select[name=corr_type]').change(on_corr_method_change); on_dataset_change = function() { let dataset_type = $('select[name=corr_dataset] option:selected').data('type'); + let location_type = $('select[name=location_type] option:selected').val(); if (dataset_type == "mrna_assay"){ $('#min_expr_filter').show(); - $('#location_filter').show(); + $('select[name=location_type] option:disabled').prop('disabled', false) } else if (dataset_type == "pheno"){ $('#min_expr_filter').show(); - $('#location_filter').hide(); + $('select[name=location_type]>option:eq(0)').prop('disabled', true).attr('selected', false); + $('select[name=location_type]>option:eq(1)').prop('disabled', false).attr('selected', true); } else { $('#min_expr_filter').hide(); - $('#location_filter').show(); + $('select[name=location_type]>option:eq(0)').prop('disabled', false).attr('selected', true); + $('select[name=location_type]>option:eq(1)').prop('disabled', true).attr('selected', false); } } + $('select[name=corr_dataset]').change(on_dataset_change); +$('select[name=location_type]').change(on_dataset_change); submit_special = function(url) { get_table_contents_for_form_submit("trait_data_form"); -- cgit v1.2.3 From 8dd6f67d37c2d5cc800ee9dc33dd13a566e256fa Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Dec 2020 15:48:50 -0600 Subject: Incorporated location_type into the filtering logic for the correlation page --- wqflask/wqflask/correlation/show_corr_results.py | 37 +++++++++++++++--------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 298a3559..6175dc7e 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -101,11 +101,12 @@ class CorrelationResults(object): 'min_loc_mb' in start_vars and 'max_loc_mb' in start_vars): + self.location_type = get_string(start_vars, 'location_type') self.location_chr = get_string(start_vars, 'loc_chr') self.min_location_mb = get_int(start_vars, 'min_loc_mb') self.max_location_mb = get_int(start_vars, 'max_loc_mb') else: - self.location_chr = self.min_location_mb = self.max_location_mb = None + self.location_type = self.location_chr = self.min_location_mb = self.max_location_mb = None self.get_formatted_corr_type() self.return_number = int(start_vars['corr_return_results']) @@ -173,23 +174,25 @@ class CorrelationResults(object): self.correlation_data = collections.OrderedDict(sorted(list(self.correlation_data.items()), key=lambda t: -abs(t[1][0]))) - if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": - #ZS: Convert min/max chromosome to an int for the location range option - range_chr_as_int = None - for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): - if 'loc_chr' in start_vars: - if chr_info.name == self.location_chr: - range_chr_as_int = order_id + + #ZS: Convert min/max chromosome to an int for the location range option + range_chr_as_int = None + for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): + if 'loc_chr' in start_vars: + if chr_info.name == self.location_chr: + range_chr_as_int = order_id for _trait_counter, trait in enumerate(list(self.correlation_data.keys())[:self.return_number]): trait_object = create_trait(dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False) if not trait_object: continue - if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": - #ZS: Convert trait chromosome to an int for the location range option - chr_as_int = 0 - for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): + chr_as_int = 0 + for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): + if self.location_type == "highest_lod": + if chr_info.name == trait_object.locus_chr: + chr_as_int = order_id + else: if chr_info.name == trait_object.chr: chr_as_int = order_id @@ -199,9 +202,15 @@ class CorrelationResults(object): if (self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Publish") and bool(trait_object.mean): if (self.min_expr != None) and (float(trait_object.mean) < self.min_expr): continue - if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": - if range_chr_as_int != None and (chr_as_int != range_chr_as_int): + + if range_chr_as_int != None and (chr_as_int != range_chr_as_int): + continue + if self.location_type == "highest_lod": + if (self.min_location_mb != None) and (float(trait_object.locus_mb) < float(self.min_location_mb)): + continue + if (self.max_location_mb != None) and (float(trait_object.locus_mb) > float(self.max_location_mb)): continue + else: if (self.min_location_mb != None) and (float(trait_object.mb) < float(self.min_location_mb)): continue if (self.max_location_mb != None) and (float(trait_object.mb) > float(self.max_location_mb)): -- cgit v1.2.3 From dd2c510ea09ea3169cac3685b299640226d5606a Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Sun, 27 Dec 2020 23:17:36 +0300 Subject: update tests for run gemma --- .../wqflask/marker_regression/test_gemma_mapping.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py index eab6afe6..fe2569b8 100644 --- a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py +++ b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py @@ -144,21 +144,26 @@ class TestGemmaMapping(unittest.TestCase): "files": [["file_name", "user", "~/file1"], ["file_name", "user", "~/file2"]] } - return_file_1 = """X/Y\t L1\t21\tQ\tE\tA\tP\tMMB\tCDE\t0.5 -X/Y\tL2\t21322\tQ\tE\tA\tP\tMMB\tCDE\t0.5 -chr\tL3\t12312\tQ\tE\tA\tP\tMMB\tCDE\t0.7""" - return_file_2 = """chr\tother\t21322\tQ\tE\tA\tP\tMMB\tCDE\t0.5""" + return_file="""X/Y\tM1\t28.457155\tQ\tE\tA\tMMB\t23.3\tW\t0.9\t0.85\t +chr4\tM2\t12\tQ\tE\tMMB\tR\t24\tW\t0.87\t0.5 +Y\tM4\t12\tQ\tE\tMMB\tR\t11.6\tW\t0.21\t0.7 +X\tM5\t12\tQ\tE\tMMB\tR\t21.1\tW\t0.65\t0.6""" + + return_file_2 = """chr\tother\t21322\tQ\tE\tA\tP\tMMB\tCDE\t0.5\t0.4""" mock_os.path.isfile.return_value = True file_to_write = """{"files":["file_1","file_2"]}""" with mock.patch("builtins.open") as mock_open: handles = (mock.mock_open(read_data="gwas").return_value, mock.mock_open( - read_data=return_file_1).return_value, mock.mock_open(read_data=return_file_2).return_value) + read_data=return_file).return_value, mock.mock_open(read_data=return_file_2).return_value) mock_open.side_effect = handles results = parse_loco_output( this_dataset={}, gwa_output_filename=".xw/") - expected_results = [{'name': ' L1', 'chr': 'X/Y', 'Mb': 2.1e-05, 'p_value': 0.5, 'lod_score': 0.3010299956639812}, { - 'name': 'L2', 'chr': 'X/Y', 'Mb': 0.021322, 'p_value': 0.5, 'lod_score': 0.3010299956639812}] + expected_results= [ + {'name': 'M1', 'chr': 'X/Y', 'Mb': 2.8457155e-05, 'p_value': 0.85, 'additive': 23.3, 'lod_score': 0.07058107428570727}, + {'name': 'M2', 'chr': 4, 'Mb': 1.2e-05, 'p_value': 0.5, 'additive': 24.0, 'lod_score': 0.3010299956639812}, + {'name': 'M4', 'chr': 'Y', 'Mb': 1.2e-05, 'p_value': 0.7, 'additive': 11.6, 'lod_score': 0.1549019599857432}, + {'name': 'M5', 'chr': 'X', 'Mb': 1.2e-05, 'p_value': 0.6, 'additive': 21.1, 'lod_score': 0.22184874961635637}] self.assertEqual(expected_results, results) -- cgit v1.2.3 From e7324bf55b7dcfd46f7a2ab52765977fb189c26b Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 29 Dec 2020 13:12:48 -0600 Subject: Added location_type to the list of inputs to correlation page (a list of form inputs the correlation page needs is passed with it so it doesn't get unrelated form inputs) --- wqflask/wqflask/static/new/javascript/show_trait.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index a301615b..83d4f193 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -566,7 +566,7 @@ get_table_contents_for_form_submit = function(form_id) { } var corr_input_list = ['corr_type', 'primary_samples', 'trait_id', 'dataset', 'group', 'tool_used', 'form_url', 'corr_sample_method', 'corr_samples_group', 'corr_dataset', 'min_expr', - 'corr_return_results', 'loc_chr', 'min_loc_mb', 'max_loc_mb', 'p_range_lower', 'p_range_upper'] + 'corr_return_results', 'location_type', 'loc_chr', 'min_loc_mb', 'max_loc_mb', 'p_range_lower', 'p_range_upper'] $(".corr_compute").on("click", (function(_this) { return function() { -- cgit v1.2.3 From 1bd2d85624e04966ed20ec84dc6ba2cfda85d794 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 29 Dec 2020 15:03:22 -0600 Subject: Used a try/catch to deal with situations where there's no SE/var column, since apparently var_nodes wasn't undefined, causing the previous check to not work --- wqflask/wqflask/static/new/javascript/show_trait.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 6918cf34..1025233b 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -448,15 +448,15 @@ edit_data_change = function() { if (is_number(sample_val) && sample_val !== "") { sample_val = parseFloat(sample_val); sample_sets[table].add_value(sample_val); - if (typeof var_nodes === 'undefined'){ - sample_var = null; - } else { + try { sample_var = var_nodes[_j].childNodes[0].value if (is_number(sample_var)) { sample_var = parseFloat(sample_var) } else { sample_var = null; } + } catch { + sample_var = null; } sample_dict = { value: sample_val, -- cgit v1.2.3 From 7d8e41cd6d31c51adfedcf7abc0da553dd58762c Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:04:55 -0600 Subject: Removed logging line from draw_probability_plot.js --- wqflask/wqflask/static/new/javascript/draw_probability_plot.js | 1 - 1 file changed, 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/draw_probability_plot.js b/wqflask/wqflask/static/new/javascript/draw_probability_plot.js index 3d756303..1b944d4f 100644 --- a/wqflask/wqflask/static/new/javascript/draw_probability_plot.js +++ b/wqflask/wqflask/static/new/javascript/draw_probability_plot.js @@ -118,7 +118,6 @@ }; }; data = [make_data('samples_primary'), make_data('samples_other')]; - console.log("THE DATA IS:", data); d3.select("#prob_plot_container svg").datum(data).call(chart); if (js_data.trait_symbol != null) { $("#prob_plot_title").html("<h3>" + js_data.trait_symbol + ": " + js_data.trait_id + "</h3>"); -- cgit v1.2.3 From 1e8c9e4bbc2f8b2085eaf77f469001660cf3c43d Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:12:02 -0600 Subject: Increased the top margin on the trait page Bar Chart, which should prevent the chart options from overlapping with the title --- wqflask/wqflask/static/new/javascript/show_trait.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 1025233b..66f7b606 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -1302,7 +1302,7 @@ if (js_data.num_values < 256) { margin: { l: left_margin, r: 30, - t: 30, + t: 100, b: bottom_margin } }; -- cgit v1.2.3 From 683381f1c98afa58cc40f1a1f000f5e136c931e3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:15:55 -0600 Subject: Removed Scatterplot Matrix since it isn't working and wasn't really used to begin with --- wqflask/wqflask/static/new/javascript/show_trait.js | 18 ------------------ wqflask/wqflask/templates/show_trait_statistics.html | 16 ---------------- 2 files changed, 34 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 66f7b606..832dd1e4 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -94,25 +94,7 @@ add = function() { $('#add_to_collection').click(add); sample_lists = js_data.sample_lists; sample_group_types = js_data.sample_group_types; -d3.select("#select_compare_trait").on("click", (function(_this) { - return function() { - $('.scatter-matrix-container').remove(); - return open_trait_selection(); - }; -})(this)); -$(".select_covariates").click(function () { - open_covariate_selection(); -}); -$(".remove_covariates").click(function () { - $("input[name=covariates]").val("") - $(".selected-covariates").val("") -}); -d3.select("#clear_compare_trait").on("click", (function(_this) { - return function() { - return $('.scatter-matrix-container').remove(); - }; -})(this)); open_trait_selection = function() { return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) { return function() { diff --git a/wqflask/wqflask/templates/show_trait_statistics.html b/wqflask/wqflask/templates/show_trait_statistics.html index 4f347d4e..865959b1 100644 --- a/wqflask/wqflask/templates/show_trait_statistics.html +++ b/wqflask/wqflask/templates/show_trait_statistics.html @@ -21,9 +21,6 @@ <li> <a href="#violin_plot_tab" class="violin_plot_tab" data-toggle="tab">Violin Plot</a> </li> - <li> - <a href="#scatterplot_matrix" data-toggle="tab">Scatterplot Matrix</a> - </li> </ul> <div class="tab-content"> <div class="tab-pane active" id="stats_tab"> @@ -116,19 +113,6 @@ <div id="violin_plot"></div> </div> </div> - <div class="tab-pane" id="scatterplot_matrix"> - <div class="btn-group scatterplot-btn-div"> - <button type="button" class="btn btn-default" id="select_compare_trait"> - <i class="icon-th-large"></i> Select Traits - </button> - <button type="button" class="btn btn-default" id="clear_compare_trait"> - <i class="icon-trash"></i> Clear - </button> - </div> - <div id="scatterplot_container"> - <div id="comparison_scatterplot" class="qtlcharts"></div> - </div> - </div> </div> </div> <div id="collections_holder_wrapper" style="display:none;"> -- cgit v1.2.3 From 257484870e4d2d0f95ea7175db2fc867154ca07f Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:16:38 -0600 Subject: Removed some logging from stats.js --- wqflask/wqflask/static/new/javascript/stats.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/stats.js b/wqflask/wqflask/static/new/javascript/stats.js index 4df03412..6c443ab3 100644 --- a/wqflask/wqflask/static/new/javascript/stats.js +++ b/wqflask/wqflask/static/new/javascript/stats.js @@ -91,8 +91,6 @@ Stats = (function() { Stats.prototype.interquartile = function() { var iq, length, q1, q3; length = this.the_values.length; - console.log("in interquartile the_values are:", this.the_values); - console.log("length is:", length); if (js_data.dataset_type == "ProbeSet" && js_data.data_scale == "linear_positive") { q1 = Math.log2(this.the_values[Math.floor(length * .25)]); q3 = Math.log2(this.the_values[Math.floor(length * .75)]); -- cgit v1.2.3 From a344835cefaaad5b8a7b96977d3963dc3cb4111e Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:45:17 -0600 Subject: Added call to change_buttons to mapping results table (which deals with highlighting rows and enabling the Add (to collection) button Also added a "check_node" paramter to change_buttons since sometimes the checkbox is in the second node instead of the first when it's preceded by blank text --- wqflask/wqflask/static/new/javascript/search_results.js | 4 ++-- wqflask/wqflask/templates/mapping_results.html | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/search_results.js b/wqflask/wqflask/static/new/javascript/search_results.js index 9ffef4f8..05dcfda5 100644 --- a/wqflask/wqflask/static/new/javascript/search_results.js +++ b/wqflask/wqflask/static/new/javascript/search_results.js @@ -1,4 +1,4 @@ -change_buttons = function() { +change_buttons = function(check_node = 0) { var button, buttons, item, num_checked, text, _i, _j, _k, _l, _len, _len2, _len3, _len4, _results, _results2; buttons = ["#add", "#remove"]; @@ -6,7 +6,7 @@ change_buttons = function() { table_api = $('#trait_table').DataTable(); check_cells = table_api.column(0).nodes().to$(); for (let i = 0; i < check_cells.length; i++) { - if (check_cells[i].childNodes[0].checked){ + if (check_cells[i].childNodes[check_node].checked){ num_checked += 1 } } diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 1a76ef7a..022e9f6a 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -375,6 +375,20 @@ console.time("Creating table"); {% if selectedChr == -1 %} $('#trait_table').DataTable( { + "drawCallback": function( settings ) { + $('#trait_table tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected")){ + $(this).removeClass("selected") + } else { + $(this).addClass("selected") + } + change_buttons(check_node=1) + }); + }, "columns": [ { "type": "natural", "width": "5%" }, { "type": "natural", "width": "8%" }, -- cgit v1.2.3 From 5fdcf24585ebff01b36d59d0ce1955cfc90fb482 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:53:08 -0600 Subject: Only show Add button and run change_buttons function when genotypes are databased --- wqflask/wqflask/templates/mapping_results.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 022e9f6a..985d542c 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -248,7 +248,7 @@ <button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button> <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button> <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button> - <button class="btn btn-success" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button> + {% if geno_db_exists == "True" %}<button class="btn btn-success" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button>{% endif %} <br /> <br /> <div id="table_container" style="width:{% if 'additive' in trimmed_markers[0] %}600{% else %}550{% endif %}px;"> @@ -386,7 +386,7 @@ } else { $(this).addClass("selected") } - change_buttons(check_node=1) + {% if geno_db_exists == "True" %}change_buttons(check_node=1){% endif %} }); }, "columns": [ -- cgit v1.2.3 From 468ab300c1447af0ac0eb3fdf12d6b6676f4a60f Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 4 Jan 2021 13:54:55 -0600 Subject: Removed logging line from init_genome_browser.js --- wqflask/wqflask/static/new/javascript/init_genome_browser.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/init_genome_browser.js b/wqflask/wqflask/static/new/javascript/init_genome_browser.js index 2552fb04..508f5bf2 100644 --- a/wqflask/wqflask/static/new/javascript/init_genome_browser.js +++ b/wqflask/wqflask/static/new/javascript/init_genome_browser.js @@ -1,5 +1,3 @@ -console.log("THE FILES:", js_data.browser_files) - snps_filename = "/browser_input?filename=" + js_data.browser_files[0] annot_filename = "/browser_input?filename=" + js_data.browser_files[1] -- cgit v1.2.3 From 7032f7b05deac0bbd2e868ffd3fe42dd1c97fb7d Mon Sep 17 00:00:00 2001 From: uditgulati Date: Tue, 5 Jan 2021 13:14:08 -0600 Subject: add server side class unit tests --- wqflask/tests/unit/wqflask/test_server_side.py | 31 ++++++++++++++++++++++++++ wqflask/wqflask/server_side.py | 16 ++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 wqflask/tests/unit/wqflask/test_server_side.py diff --git a/wqflask/tests/unit/wqflask/test_server_side.py b/wqflask/tests/unit/wqflask/test_server_side.py new file mode 100644 index 00000000..4f91d8ca --- /dev/null +++ b/wqflask/tests/unit/wqflask/test_server_side.py @@ -0,0 +1,31 @@ +import unittest + +from wqflask.server_side import ServerSideTable + + +class TestServerSideTableTests(unittest.TestCase): + """ + Test the ServerSideTable class + + test table: + first, second, third + 'd', 4, 'zz' + 'b', 2, 'aa' + 'c', 1, 'ss' + """ + + def test_get_page(self): + rows_count = 3 + table_rows = [ + {'first': 'd', 'second': 4, 'third': 'zz'}, + {'first': 'b', 'second': 2, 'third': 'aa'}, + {'first': 'c', 'second': 1, 'third': 'ss'}, + ] + headers = ['first', 'second', 'third'] + request_args = {'sEcho': '1', 'iSortCol_0': '1', 'iSortingCols': '1', 'sSortDir_0': 'asc', 'iDisplayStart': '0', 'iDisplayLength': '3'} + + test_page = ServerSideTable(rows_count, table_rows, headers, request_args).get_page() + self.assertEqual(test_page['sEcho'], '1') + self.assertEqual(test_page['iTotalRecords'], 'nan') + self.assertEqual(test_page['iTotalDisplayRecords'], '3') + self.assertEqual(test_page['data'], [{'first': 'b', 'second': 2, 'third': 'aa'}, {'first': 'c', 'second': 1, 'third': 'ss'}, {'first': 'd', 'second': 4, 'third': 'zz'}]) diff --git a/wqflask/wqflask/server_side.py b/wqflask/wqflask/server_side.py index 824b00aa..5f764767 100644 --- a/wqflask/wqflask/server_side.py +++ b/wqflask/wqflask/server_side.py @@ -3,7 +3,7 @@ class ServerSideTable(object): - ''' + """ This class is used to do server-side processing on the DataTables table such as paginating, sorting, filtering(not implemented) etc. This takes the load off @@ -22,7 +22,7 @@ class ServerSideTable(object): Have a look at snp_browser_table() function in wqflask/wqflask/views.py for reference use. - ''' + """ def __init__(self, rows_count, table_rows, header_data_names, request_values): self.request_values = request_values @@ -36,12 +36,12 @@ class ServerSideTable(object): self.paginate_rows() def sort_rows(self): - ''' + """ Sorts the rows taking in to account the column (or columns) that the user has selected. - ''' + """ def is_reverse(str_direction): - ''' Maps the 'desc' and 'asc' words to True or False. ''' + """ Maps the 'desc' and 'asc' words to True or False. """ return True if str_direction == 'desc' else False if (self.request_values['iSortCol_0'] != "") and (int(self.request_values['iSortingCols']) > 0): @@ -54,12 +54,12 @@ class ServerSideTable(object): reverse=is_reverse(sort_direction)) def paginate_rows(self): - ''' + """ Selects a subset of the filtered and sorted data based on if the table has pagination, the current page and the size of each page. - ''' + """ def requires_pagination(): - ''' Check if the table is going to be paginated ''' + """ Check if the table is going to be paginated """ if self.request_values['iDisplayStart'] != "": if int(self.request_values['iDisplayLength']) != -1: return True -- cgit v1.2.3 From 0ef495b69d99c53e7a6a216e6748898dbcc79eec Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 5 Jan 2021 15:24:10 -0600 Subject: Fixed issue where normalization method wasn't removed from stats figure axis titles when table values are reset --- wqflask/wqflask/static/new/javascript/show_trait.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 832dd1e4..765f2f2d 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -207,6 +207,8 @@ update_histogram = function() { if ($('input[name="transform"]').val() != ""){ root.histogram_layout['xaxis']['title'] = "<b>" + js_data.unit_type + " (" + $('input[name="transform"]').val() + ")</b>" + } else { + root.histogram_layout['xaxis']['title'] = "<b>" + js_data.unit_type + "</b>" } Plotly.newPlot('histogram', root.histogram_data, root.histogram_layout, root.modebar_options); @@ -255,6 +257,8 @@ update_bar_chart = function() { if ($('input[name="transform"]').val() != ""){ root.bar_layout['yaxis']['title'] = "<b>" + js_data.unit_type + " (" + $('input[name="transform"]').val() + ")</b>" + } else { + root.bar_layout['yaxis']['title'] = "<b>" + js_data.unit_type + "</b>" } root.bar_data[0]['y'] = trait_vals @@ -296,6 +300,8 @@ update_box_plot = function() { if ($('input[name="transform"]').val() != ""){ root.box_layout['yaxis']['title'] = "<b>" + js_data.unit_type + " (" + $('input[name="transform"]').val() + ")</b>" + } else { + root.box_layout['yaxis']['title'] = "<b>" + js_data.unit_type + "</b>" } Plotly.newPlot('box_plot', root.box_data, root.box_layout, root.modebar_options) @@ -327,6 +333,8 @@ update_violin_plot = function() { if ($('input[name="transform"]').val() != ""){ root.violin_layout['yaxis']['title'] = "<b>" + js_data.unit_type + " (" + $('input[name="transform"]').val() + ")</b>" + } else { + root.violin_layout['yaxis']['title'] = "<b>" + js_data.unit_type + "</b>" } Plotly.newPlot('violin_plot', root.violin_data, root.violin_layout, root.modebar_options) @@ -795,6 +803,7 @@ reset_samples_table = function() { }; $('.reset').click(function() { reset_samples_table(); + $('input[name="transform"]').val(""); edit_data_change(); }); -- cgit v1.2.3 From 2bd74f8f4e4e72a11c77d4f3e8532c303503ca11 Mon Sep 17 00:00:00 2001 From: Alexanderlacuna Date: Mon, 16 Nov 2020 13:46:57 +0300 Subject: add unit tests for api/mapping.py --- wqflask/tests/unit/wqflask/api/test_mapping.py | 114 +++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 wqflask/tests/unit/wqflask/api/test_mapping.py diff --git a/wqflask/tests/unit/wqflask/api/test_mapping.py b/wqflask/tests/unit/wqflask/api/test_mapping.py new file mode 100644 index 00000000..87b18e84 --- /dev/null +++ b/wqflask/tests/unit/wqflask/api/test_mapping.py @@ -0,0 +1,114 @@ +import unittest +from unittest import mock +from wqflask.api.mapping import initialize_parameters + + +class AttributeSetter: + def __init__(self,obj): + for key,value in obj.items(): + setattr(self,key,value) + +class MockGroup(AttributeSetter): + def get_marker(self): + return None +class TestMock(unittest.TestCase): + + # @mock.patch("wqflask.api.mapping.gemma_mapping") + # @mock.patch("wqflask.api.mapping.nitialize_parameters") + # @mock.patch("wqflask.api.mapping.retrieve_sample_data") + # @mock.patch("wqflask.api.mapping.create_trait") + # @mock.patch("wqflask.api.mapping.data_set") + # def test_do_mapping_for_api(self,mock_dataset,mock_create_trait,mock_retrieve_data,mock_gemma): + + # start_vars={ + # "db":"sql_uri/db_web1", + # "trait_id":"idsui332rh3ui2t", + # "limit_to":32.1, + # } + # group_samplelist=["S1","S2","S3","S4"] + # dataset_group=MockGroup({"samplelist":group_samplelist}) + # dataset=AttributeSetter({"type":"Temp","group":dataset_group}) + + # this_trait_data={ + # "Item1":AttributeSetter({ + # "name":"S1", + # "value":"V1" + # }), + + # "Item2":AttributeSetter({ + # "name":"S2", + # "value":"V2" + # }), + + # "Item3":AttributeSetter({ + # "name":"SX", + # "value":"VX" + # }) + # } + + # this_trait=AttributeSetter({"data":this_trait_data}) + + + # mock_dataset.create_dataset.return_value=dataset + + # mock_create_trait.return_value=this_trait + # mock_retrieve_data.return_value=this_trait + + # mock_initialize_params={ + # "format":"json", + # "limit_to":32.1, + # "mapping_method":"gemma", + # "maf":0.01, + # "use_loco":True, + # "num_perm":0, + # "perm_check":False + + # } + + # mock_gemma.return_value=[ ,"filename"] + # pass + + def test_initialize_parameters(self): + expected_results={ + "format":"json", + "limit_to":False, + "mapping_method":"gemma", + "maf":0.01, + "use_loco":True, + "num_perm":0, + "perm_check":False + } + + results=initialize_parameters(start_vars={},dataset={},this_trait={}) + self.assertEqual(results,expected_results) + + start_vars={ + "format":"F1", + "limit_to":"1", + "mapping_method":"rqtl", + "control_marker":True, + "pair_scan":"true", + "interval_mapping":"true", + "use_loco":"true", + "num_perm":"14" + + } + + results_2=initialize_parameters(start_vars=start_vars,dataset={},this_trait={}) + expected_results={ + "format":"F1", + "limit_to":1, + "mapping_method":"gemma", + "maf":0.01, + "use_loco":True, + "num_perm":14, + "perm_check":"ON" + } + + self.assertEqual(results_2,expected_results) + + + + + + -- cgit v1.2.3 From df2c3f9ee43dd055f7766eedee32d76090ad80b2 Mon Sep 17 00:00:00 2001 From: Alexanderlacuna Date: Mon, 16 Nov 2020 13:47:40 +0300 Subject: add unit testsfor api/correlation.py --- wqflask/tests/unit/wqflask/api/test_correlation.py | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 wqflask/tests/unit/wqflask/api/test_correlation.py diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py new file mode 100644 index 00000000..482dec67 --- /dev/null +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -0,0 +1,83 @@ +import unittest +from unittest import mock +from wqflask import app +from wqflask.api.correlation import init_corr_params +from wqflask.api.correlation import convert_to_mouse_gene_id +from wqflask.api.correlation import do_literature_correlation_for_all_traits + + +class AttributeSetter: + def __init__(self, obj): + for k, v in obj.items(): + setattr(self, k, v) + + +class TestCorrelations(unittest.TestCase): + def setUp(self): + self.app_context = app.app_context() + self.app_context.push() + + def tearDown(self): + self.app_context.pop() + + def test_init_corr_params(self): + start_vars = { + "return_count": "3", + "type": "T1", + "method": "spearman" + } + + corr_params_results = init_corr_params(start_vars=start_vars) + expected_results = { + "return_count": 3, + "type": "T1", + "method": "spearman" + } + + self.assertEqual(corr_params_results, expected_results) + + @mock.patch("wqflask.api.correlation.g") + def test_convert_to_mouse_gene_id(self, mock_db): + + results = convert_to_mouse_gene_id(species="Other", gene_id="") + self.assertEqual(results, None) + + rat_species_results = convert_to_mouse_gene_id( + species="rat", gene_id="GH1") + + mock_db.db.execute.return_value.fetchone.side_effect = [AttributeSetter({"mouse": "MG-1"}),AttributeSetter({"mouse":"MG-2"})] + + self.assertEqual(convert_to_mouse_gene_id( + species="mouse", gene_id="MG-4"), "MG-4") + self.assertEqual(convert_to_mouse_gene_id( + species="rat", gene_id="R1"), "MG-1") + self.assertEqual(convert_to_mouse_gene_id( + species="human", gene_id="H1"), "MG-2") + + + + @mock.patch("wqflask.api.correlation.g") + @mock.patch("wqflask.api.correlation.convert_to_mouse_gene_id") + def test_do_literature_correlation_for_all_traits(self,mock_convert_to_mouse_geneid,mock_db): + mock_convert_to_mouse_geneid.side_effect=["MG-1","MG-2;","MG-3","MG-4"] + + + trait_geneid_dict={ + "TT-1":"GH-1", + "TT-2":"GH-2", + "TT-3":"GH-3" + + } + mock_db.db.execute.return_value.fetchone.side_effect=[AttributeSetter({"value":"V1"}),AttributeSetter({"value":"V2"}),AttributeSetter({"value":"V3"})] + + + this_trait=AttributeSetter({"geneid":"GH-1"}) + + target_dataset=AttributeSetter({"group":AttributeSetter({"species":"rat"})}) + results=do_literature_correlation_for_all_traits(this_trait=this_trait,target_dataset=target_dataset,trait_geneid_dict=trait_geneid_dict,corr_params={}) + + expected_results={'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 'V1'], 'TT-3': ['GH-3', 'V2']} + self.assertEqual(results,expected_results) + + + -- cgit v1.2.3 From 3eda2b13e10937cbd661d6d411286c5b84bcd7cf Mon Sep 17 00:00:00 2001 From: Alexanderlacuna Date: Sat, 28 Nov 2020 15:00:00 +0300 Subject: add correlation test --- .../correlation/test_correlation_functions.py | 21 +++++ .../wqflask/correlation/test_show_corr_results.py | 95 ++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py create mode 100644 wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py diff --git a/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py new file mode 100644 index 00000000..db449eb1 --- /dev/null +++ b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py @@ -0,0 +1,21 @@ +import unittest +from unittest import mock +from wqflask.correlation.correlation_functions import get_trait_symbol_and_tissue_values +from wqflask.correlation.correlation_functions import cal_zero_order_corr_for_tiss + + +class TestCorrelationFunctions(unittest.TestCase): + + + @mock.patch("wqflask.correlation.correlation_functions.MrnaAssayTissueData") + def test_get_trait_symbol_and_tissue_values(self, mock_class): + """test for getting trait symbol and tissue_values""" + mock_class_instance = mock_class.return_value + mock_class_instance.gene_symbols = ["k1", "k2", "k3"] + mock_class_instance.get_symbol_values_pairs.return_value = { + "k1": ["v1", "v2", "v3"], "k2": ["v2", "v3"], "k3": ["k3"]} + results = get_trait_symbol_and_tissue_values( + symbol_list=["k1", "k2", "k3"]) + mock_class.assert_called_with(gene_symbols=['k1', 'k2', 'k3']) + self.assertEqual({"k1": ["v1", "v2", "v3"], "k2": [ + "v2", "v3"], "k3": ["k3"]}, results) diff --git a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py new file mode 100644 index 00000000..4e63207e --- /dev/null +++ b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py @@ -0,0 +1,95 @@ +import unittest +from unittest import mock +from wqflask.correlation.show_corr_results import get_header_fields +from wqflask.correlation.show_corr_results import generate_corr_json +from wqflask.correlation.show_corr_results import do_bicor + + +class Trait: + def __init__(self,trait_obj): + for key,value in trait_obj.items(): + setattr(self,key,value) + +class TestShowCorrResults(unittest.TestCase): + + def test_process_samples(self): + pass + def test_get_header_fields(self): + expected=[ + ['Index', + 'Record', + 'Symbol', + 'Description', + 'Location', + 'Mean', + 'Sample rho', + 'N', + 'Sample p(rho)', + 'Lit rho', + 'Tissue rho', + 'Tissue p(rho)', + 'Max LRS', + 'Max LRS Location', + 'Additive Effect'], + + ['Index', + 'ID', + 'Location', + 'Sample r', + 'N', + 'Sample p(r)'] + + ] + result1=get_header_fields("ProbeSet","spearman") + result2=get_header_fields("Other","Other") + self.assertEqual(result1,expected[0]) + self.assertEqual(result2,expected[1]) + + + + + def test_generate_corr_json(self): + this_trait=Trait({"name":"trait_test"}) + dataset=Trait({"name":"the_name"}) + target_dataset=Trait({"type":"Publish"}) + + trait_with_publish={ + "description_display":"Trait 2 description", + "authors":"trait_2 ", + "pubmed_id":"34n4nn31hn43", + "lrs_location":"N/A", + "additive":"", + "sample_r":100, + "num_overlap":3.2, + "view":True, + "name":"trait_1", + "pubmed_text":"2016", + "additive":"", + "sample_r":10.5, + "LRS_score_repr":"N/A", + "LRS_location_repr":"N/A", + "sample_p":5, + "num_overlap":"num_1" + + + + } + expected_results="""[{"trait_id": "trait_1", "description": "Trait 2 description", "authors": "trait_2 ", "pubmed_id": "34n4nn31hn43", "year": "2016", "lrs_score": "N/A", "lrs_location": "N/A", "additive": "N/A", "sample_r": "10.500", "num_overlap": "num_1", "sample_p": "5.000e+00"}]""" + + corr_results=[Trait(trait_with_publish)] + results=generate_corr_json(corr_results=corr_results,this_trait=this_trait,dataset=dataset,target_dataset=target_dataset,for_api=True) + self.assertEqual(results,expected_results) + + + + def test_generate_corr_json_view_false(self): + trait=Trait({"view":False}) + corr_results=[trait] + this_trait=Trait({"name":"trait_test"}) + dataset=Trait({"name":"the_name"}) + + + results_where_view_is_false=generate_corr_json(corr_results=corr_results,this_trait=this_trait,dataset={},target_dataset={},for_api=False) + + # self.assertEqual(results,[]) + self.assertEqual(results_where_view_is_false,"[]") \ No newline at end of file -- cgit v1.2.3 From 1666f8d50df090e9a14dbf0f4f195bac079de058 Mon Sep 17 00:00:00 2001 From: Alexanderlacuna Date: Sat, 28 Nov 2020 15:11:06 +0300 Subject: add test in api/mapping --- wqflask/tests/unit/wqflask/api/test_mapping.py | 55 -------------------------- 1 file changed, 55 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_mapping.py b/wqflask/tests/unit/wqflask/api/test_mapping.py index 87b18e84..4da1725f 100644 --- a/wqflask/tests/unit/wqflask/api/test_mapping.py +++ b/wqflask/tests/unit/wqflask/api/test_mapping.py @@ -13,61 +13,6 @@ class MockGroup(AttributeSetter): return None class TestMock(unittest.TestCase): - # @mock.patch("wqflask.api.mapping.gemma_mapping") - # @mock.patch("wqflask.api.mapping.nitialize_parameters") - # @mock.patch("wqflask.api.mapping.retrieve_sample_data") - # @mock.patch("wqflask.api.mapping.create_trait") - # @mock.patch("wqflask.api.mapping.data_set") - # def test_do_mapping_for_api(self,mock_dataset,mock_create_trait,mock_retrieve_data,mock_gemma): - - # start_vars={ - # "db":"sql_uri/db_web1", - # "trait_id":"idsui332rh3ui2t", - # "limit_to":32.1, - # } - # group_samplelist=["S1","S2","S3","S4"] - # dataset_group=MockGroup({"samplelist":group_samplelist}) - # dataset=AttributeSetter({"type":"Temp","group":dataset_group}) - - # this_trait_data={ - # "Item1":AttributeSetter({ - # "name":"S1", - # "value":"V1" - # }), - - # "Item2":AttributeSetter({ - # "name":"S2", - # "value":"V2" - # }), - - # "Item3":AttributeSetter({ - # "name":"SX", - # "value":"VX" - # }) - # } - - # this_trait=AttributeSetter({"data":this_trait_data}) - - - # mock_dataset.create_dataset.return_value=dataset - - # mock_create_trait.return_value=this_trait - # mock_retrieve_data.return_value=this_trait - - # mock_initialize_params={ - # "format":"json", - # "limit_to":32.1, - # "mapping_method":"gemma", - # "maf":0.01, - # "use_loco":True, - # "num_perm":0, - # "perm_check":False - - # } - - # mock_gemma.return_value=[ ,"filename"] - # pass - def test_initialize_parameters(self): expected_results={ "format":"json", -- cgit v1.2.3 From 7b1d35701c283973ab63db3b665951f569a8c5fc Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Sun, 29 Nov 2020 17:30:43 +0300 Subject: refactor code in correlation/correlation_functions --- .../wqflask/correlation/correlation_functions.py | 28 ---------------------- 1 file changed, 28 deletions(-) diff --git a/wqflask/wqflask/correlation/correlation_functions.py b/wqflask/wqflask/correlation/correlation_functions.py index b883e361..fd7691d4 100644 --- a/wqflask/wqflask/correlation/correlation_functions.py +++ b/wqflask/wqflask/correlation/correlation_functions.py @@ -71,34 +71,6 @@ def cal_zero_order_corr_for_tiss (primaryValue=[], targetValue=[], method='pears return corr_result -########################################################################### -#Input: cursor, symbolList (list), dataIdDict(Dict) -#output: symbolValuepairDict (dictionary):one dictionary of Symbol and Value Pair, -# key is symbol, value is one list of expression values of one probeSet; -#function: get one dictionary whose key is gene symbol and value is tissue expression data (list type). -#Attention! All keys are lower case! -########################################################################### -def get_symbol_value_pairs(tissue_data): - id_list = [tissue_data[symbol.lower()].data_id for item in tissue_data] - - symbol_value_pairs = {} - value_list=[] - - query = """SELECT value, id - FROM TissueProbeSetData - WHERE Id IN {}""".format(create_in_clause(id_list)) - - try : - results = g.db.execute(query).fetchall() - for result in results: - value_list.append(result.value) - symbol_value_pairs[symbol] = value_list - except: - symbol_value_pairs[symbol] = None - - return symbol_value_pairs - - ######################################################################################################## #input: cursor, symbolList (list), dataIdDict(Dict): key is symbol #output: SymbolValuePairDict(dictionary):one dictionary of Symbol and Value Pair. -- cgit v1.2.3 From e535eeeff92bcfa6d6524e44591164de72d38482 Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Fri, 4 Dec 2020 18:43:35 +0300 Subject: add test for map_api in api/test_mapping.py --- wqflask/tests/unit/wqflask/api/test_mapping.py | 145 +++++++++++++++++-------- 1 file changed, 99 insertions(+), 46 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_mapping.py b/wqflask/tests/unit/wqflask/api/test_mapping.py index 4da1725f..5455b215 100644 --- a/wqflask/tests/unit/wqflask/api/test_mapping.py +++ b/wqflask/tests/unit/wqflask/api/test_mapping.py @@ -1,57 +1,110 @@ import unittest from unittest import mock from wqflask.api.mapping import initialize_parameters +from wqflask.api.mapping import do_mapping_for_api class AttributeSetter: - def __init__(self,obj): - for key,value in obj.items(): - setattr(self,key,value) + def __init__(self,obj): + for key,value in obj.items(): + setattr(self,key,value) class MockGroup(AttributeSetter): - def get_marker(self): - return None -class TestMock(unittest.TestCase): - - def test_initialize_parameters(self): - expected_results={ - "format":"json", - "limit_to":False, - "mapping_method":"gemma", - "maf":0.01, - "use_loco":True, - "num_perm":0, - "perm_check":False - } - - results=initialize_parameters(start_vars={},dataset={},this_trait={}) - self.assertEqual(results,expected_results) - - start_vars={ - "format":"F1", - "limit_to":"1", - "mapping_method":"rqtl", - "control_marker":True, - "pair_scan":"true", - "interval_mapping":"true", - "use_loco":"true", - "num_perm":"14" - - } - - results_2=initialize_parameters(start_vars=start_vars,dataset={},this_trait={}) - expected_results={ - "format":"F1", - "limit_to":1, - "mapping_method":"gemma", - "maf":0.01, - "use_loco":True, - "num_perm":14, - "perm_check":"ON" - } - - self.assertEqual(results_2,expected_results) - + def get_marker(self): + self.markers=[] +class TestMapping(unittest.TestCase): + + def test_initialize_parameters(self): + expected_results={ + "format":"json", + "limit_to":False, + "mapping_method":"gemma", + "maf":0.01, + "use_loco":True, + "num_perm":0, + "perm_check":False + } + + results=initialize_parameters(start_vars={},dataset={},this_trait={}) + self.assertEqual(results,expected_results) + + start_vars={ + "format":"F1", + "limit_to":"1", + "mapping_method":"rqtl", + "control_marker":True, + "pair_scan":"true", + "interval_mapping":"true", + "use_loco":"true", + "num_perm":"14" + + } + + results_2=initialize_parameters(start_vars=start_vars,dataset={},this_trait={}) + expected_results={ + "format":"F1", + "limit_to":1, + "mapping_method":"gemma", + "maf":0.01, + "use_loco":True, + "num_perm":14, + "perm_check":"ON" + } + + self.assertEqual(results_2,expected_results) + + + @mock.patch("wqflask.api.mapping.rqtl_mapping.run_rqtl_geno") + @mock.patch("wqflask.api.mapping.gemma_mapping.run_gemma") + @mock.patch("wqflask.api.mapping.initialize_parameters") + @mock.patch("wqflask.api.mapping.retrieve_sample_data") + @mock.patch("wqflask.api.mapping.create_trait") + @mock.patch("wqflask.api.mapping.data_set.create_dataset") + def test_do_mapping_for_api(self,mock_create_dataset,mock_trait,mock_retrieve_sample,mock_param,run_gemma + ,run_rqtl_geno): + start_vars={ + "db":"Temp", + "trait_id":"dewf3232rff2", + "format":"F1", + "mapping_method":"gemma", + "use_loco":True + + } + sampleList=["S1","S2","S3","S4"] + samplelist=["S1","S2","S4"] + dataset=AttributeSetter({"group":samplelist}) + this_trait=AttributeSetter({}) + trait_data=AttributeSetter({ + "data":{ + "item1":AttributeSetter({"name":"S1","value":"S1_value"}), + "item2":AttributeSetter({"name":"S2","value":"S2_value"}), + "item3":AttributeSetter({"name":"S3","value":"S3_value"}), + + } + }) + trait=AttributeSetter({ + "data":trait_data + }) + + dataset.return_value=dataset + mock_trait.return_value=this_trait + + mock_retrieve_sample.return_value=trait + mock_param.return_value={ + "format":"F1", + "limit_to":False, + "mapping_method":"gemma", + "maf":0.01, + "use_loco":"True", + "num_perm":14, + "perm_check":"ON" + } + + run_gemma.return_value=["results"] + results=do_mapping_for_api(start_vars=start_vars) + self.assertEqual(results,("results",None)) + + -- cgit v1.2.3 From e80e793455d2fc6b51dbe95414a3ba8e72652a83 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Sat, 12 Dec 2020 21:21:53 +0300 Subject: add tests for getting sample_r and p values --- wqflask/tests/unit/wqflask/api/test_correlation.py | 38 ++++++++++++++++++++++ .../wqflask/correlation/test_show_corr_results.py | 2 -- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py index 482dec67..077f7fa9 100644 --- a/wqflask/tests/unit/wqflask/api/test_correlation.py +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -4,6 +4,7 @@ from wqflask import app from wqflask.api.correlation import init_corr_params from wqflask.api.correlation import convert_to_mouse_gene_id from wqflask.api.correlation import do_literature_correlation_for_all_traits +from wqflask.api.correlation import get_sample_r_and_p_values class AttributeSetter: @@ -79,5 +80,42 @@ class TestCorrelations(unittest.TestCase): expected_results={'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 'V1'], 'TT-3': ['GH-3', 'V2']} self.assertEqual(results,expected_results) + @mock.patch("wqflask.api.correlation.corr_result_helpers.normalize_values") + def test_get_sample_r_and_p_values(self,mock_normalize): + + group=AttributeSetter({"samplelist":["S1","S2","S3","S4","S5","S6","S7"]}) + target_dataset=AttributeSetter({"group":group}) + + target_vals=[3.4, 6.2, 4.1,3.4,1.2,5.6] + trait_data={"S1":AttributeSetter({"value":2.3}),"S2":AttributeSetter({"value":1.1}),"S3":AttributeSetter({"value":6.3}),"S4":AttributeSetter({"value":3.6}),"S5":AttributeSetter({"value":4.1}),"S6":AttributeSetter({"value":5.0})} + this_trait=AttributeSetter({"data":trait_data}) + mock_normalize.return_value=([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6) + mock_normalize.side_effect=[([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6),([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6),([2.3,1.1,1.4], [3.4,6.2,4.1], 3)] + + results_pearsonr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") + results_spearmanr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="spearman") + results_num_overlap=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") + self.assertEqual(mock_normalize.call_count,3) + + self.assertEqual(results_pearsonr,[-0.21618688834430866, 0.680771605997119, 6]) + self.assertEqual(results_spearmanr,[-0.11595420713048969, 0.826848213385815, 6]) + self.assertEqual(results_num_overlap,None) + + def test_calculate_results(self): + corr_params={ + "type":"pearson" + } + trait_data={ + "T1":3.4, + "T2":6.2, + "T3":4.1, + "T4":3.4, + "T5":1.2, + "T6":5.6 + } + target_vals=[3.4, 6.2, 4.1,3.4,1.2,5.6] + + + diff --git a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py index 4e63207e..969a84f5 100644 --- a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py +++ b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py @@ -12,8 +12,6 @@ class Trait: class TestShowCorrResults(unittest.TestCase): - def test_process_samples(self): - pass def test_get_header_fields(self): expected=[ ['Index', -- cgit v1.2.3 From 0adae692f2f0ce509b32d6654438213deb3da89b Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Sat, 12 Dec 2020 23:09:04 +0300 Subject: add test for calculating correlation results --- wqflask/tests/unit/wqflask/api/test_correlation.py | 44 +++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py index 077f7fa9..11c7d82b 100644 --- a/wqflask/tests/unit/wqflask/api/test_correlation.py +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -1,10 +1,12 @@ import unittest from unittest import mock from wqflask import app +from collections import OrderedDict from wqflask.api.correlation import init_corr_params from wqflask.api.correlation import convert_to_mouse_gene_id from wqflask.api.correlation import do_literature_correlation_for_all_traits from wqflask.api.correlation import get_sample_r_and_p_values +from wqflask.api.correlation import calculate_results class AttributeSetter: @@ -12,6 +14,17 @@ class AttributeSetter: for k, v in obj.items(): setattr(self, k, v) +class MockDataset(AttributeSetter): + def get_trait_data(self): + return None + def retrieve_genes(self,id=None): + return { + "TT-1":"GH-1", + "TT-2":"GH-2", + "TT-3":"GH-3" + + } + class TestCorrelations(unittest.TestCase): def setUp(self): @@ -101,19 +114,24 @@ class TestCorrelations(unittest.TestCase): self.assertEqual(results_spearmanr,[-0.11595420713048969, 0.826848213385815, 6]) self.assertEqual(results_num_overlap,None) - def test_calculate_results(self): - corr_params={ - "type":"pearson" - } - trait_data={ - "T1":3.4, - "T2":6.2, - "T3":4.1, - "T4":3.4, - "T5":1.2, - "T6":5.6 - } - target_vals=[3.4, 6.2, 4.1,3.4,1.2,5.6] + @mock.patch("wqflask.api.correlation.do_literature_correlation_for_all_traits") + def test_calculate_results(self,literature_correlation): + + literature_correlation.return_value={'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1]} + + + + this_dataset=MockDataset({"group":AttributeSetter({"species":"rat"})}) + target_dataset=MockDataset({"group":AttributeSetter({"species":"rat"})}) + this_trait=AttributeSetter({"geneid":"GH-1"}) + corr_params={"type":"literature"} + sorted_results=calculate_results(this_trait=this_trait,this_dataset=this_dataset,target_dataset=target_dataset,corr_params=corr_params) + expected_results={'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1], 'TT-1': ['GH-1', 0]} + + self.assertTrue(isinstance(sorted_results,OrderedDict)) + self.assertEqual(type(sorted_results),OrderedDict) + + -- cgit v1.2.3 From b7e2d17536febbeb47dc91015781cc6fc4647905 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Sat, 12 Dec 2020 23:36:27 +0300 Subject: replace assertEqual with assertAlmostEqual for floats --- wqflask/tests/unit/wqflask/api/test_correlation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py index 11c7d82b..9fa848a4 100644 --- a/wqflask/tests/unit/wqflask/api/test_correlation.py +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -108,10 +108,12 @@ class TestCorrelations(unittest.TestCase): results_pearsonr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") results_spearmanr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="spearman") results_num_overlap=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") - self.assertEqual(mock_normalize.call_count,3) - - self.assertEqual(results_pearsonr,[-0.21618688834430866, 0.680771605997119, 6]) - self.assertEqual(results_spearmanr,[-0.11595420713048969, 0.826848213385815, 6]) + expected_pearsonr=[-0.21618688834430866, 0.680771605997119, 6] + expected_spearmanr=[-0.11595420713048969, 0.826848213385815, 6] + for i,val in enumerate(expected_pearsonr): + self.assertAlmostEqual(val,results_pearsonr[i]) + for i,val in enumerate(expected_spearmanr): + self.assertAlmostEqual(val,results_spearmanr[i]) self.assertEqual(results_num_overlap,None) @mock.patch("wqflask.api.correlation.do_literature_correlation_for_all_traits") @@ -133,7 +135,6 @@ class TestCorrelations(unittest.TestCase): - -- cgit v1.2.3 From c3bfc7c07bba06c9334350111df0b9444b85b31b Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Sat, 12 Dec 2020 23:56:26 +0300 Subject: modify tests for calculate correlation results --- wqflask/tests/unit/wqflask/api/test_correlation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py index 9fa848a4..cbcd006d 100644 --- a/wqflask/tests/unit/wqflask/api/test_correlation.py +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -131,7 +131,7 @@ class TestCorrelations(unittest.TestCase): expected_results={'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1], 'TT-1': ['GH-1', 0]} self.assertTrue(isinstance(sorted_results,OrderedDict)) - self.assertEqual(type(sorted_results),OrderedDict) + self.assertEqual(dict(sorted_results),expected_results) -- cgit v1.2.3 From d10b6a9bc3ed4d3f824a0dfd115f05ed647aa8c3 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 20:08:41 +0300 Subject: pep8 formatting and refactoring tests --- wqflask/tests/unit/wqflask/api/test_correlation.py | 145 +++++++++++---------- 1 file changed, 79 insertions(+), 66 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_correlation.py b/wqflask/tests/unit/wqflask/api/test_correlation.py index cbcd006d..d0264b87 100644 --- a/wqflask/tests/unit/wqflask/api/test_correlation.py +++ b/wqflask/tests/unit/wqflask/api/test_correlation.py @@ -1,7 +1,7 @@ import unittest from unittest import mock from wqflask import app -from collections import OrderedDict +from collections import OrderedDict from wqflask.api.correlation import init_corr_params from wqflask.api.correlation import convert_to_mouse_gene_id from wqflask.api.correlation import do_literature_correlation_for_all_traits @@ -14,14 +14,16 @@ class AttributeSetter: for k, v in obj.items(): setattr(self, k, v) + class MockDataset(AttributeSetter): def get_trait_data(self): return None - def retrieve_genes(self,id=None): + + def retrieve_genes(self, id=None): return { - "TT-1":"GH-1", - "TT-2":"GH-2", - "TT-3":"GH-3" + "TT-1": "GH-1", + "TT-2": "GH-2", + "TT-3": "GH-3" } @@ -59,8 +61,9 @@ class TestCorrelations(unittest.TestCase): rat_species_results = convert_to_mouse_gene_id( species="rat", gene_id="GH1") - mock_db.db.execute.return_value.fetchone.side_effect = [AttributeSetter({"mouse": "MG-1"}),AttributeSetter({"mouse":"MG-2"})] - + mock_db.db.execute.return_value.fetchone.side_effect = [ + AttributeSetter({"mouse": "MG-1"}), AttributeSetter({"mouse": "MG-2"})] + self.assertEqual(convert_to_mouse_gene_id( species="mouse", gene_id="MG-4"), "MG-4") self.assertEqual(convert_to_mouse_gene_id( @@ -68,73 +71,83 @@ class TestCorrelations(unittest.TestCase): self.assertEqual(convert_to_mouse_gene_id( species="human", gene_id="H1"), "MG-2") - - @mock.patch("wqflask.api.correlation.g") @mock.patch("wqflask.api.correlation.convert_to_mouse_gene_id") - def test_do_literature_correlation_for_all_traits(self,mock_convert_to_mouse_geneid,mock_db): - mock_convert_to_mouse_geneid.side_effect=["MG-1","MG-2;","MG-3","MG-4"] - - - trait_geneid_dict={ - "TT-1":"GH-1", - "TT-2":"GH-2", - "TT-3":"GH-3" + def test_do_literature_correlation_for_all_traits(self, mock_convert_to_mouse_geneid, mock_db): + mock_convert_to_mouse_geneid.side_effect = [ + "MG-1", "MG-2;", "MG-3", "MG-4"] - } - mock_db.db.execute.return_value.fetchone.side_effect=[AttributeSetter({"value":"V1"}),AttributeSetter({"value":"V2"}),AttributeSetter({"value":"V3"})] + trait_geneid_dict = { + "TT-1": "GH-1", + "TT-2": "GH-2", + "TT-3": "GH-3" + } + mock_db.db.execute.return_value.fetchone.side_effect = [AttributeSetter( + {"value": "V1"}), AttributeSetter({"value": "V2"}), AttributeSetter({"value": "V3"})] - this_trait=AttributeSetter({"geneid":"GH-1"}) + this_trait = AttributeSetter({"geneid": "GH-1"}) - target_dataset=AttributeSetter({"group":AttributeSetter({"species":"rat"})}) - results=do_literature_correlation_for_all_traits(this_trait=this_trait,target_dataset=target_dataset,trait_geneid_dict=trait_geneid_dict,corr_params={}) + target_dataset = AttributeSetter( + {"group": AttributeSetter({"species": "rat"})}) + results = do_literature_correlation_for_all_traits( + this_trait=this_trait, target_dataset=target_dataset, trait_geneid_dict=trait_geneid_dict, corr_params={}) - expected_results={'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 'V1'], 'TT-3': ['GH-3', 'V2']} - self.assertEqual(results,expected_results) + expected_results = {'TT-1': ['GH-1', 0], + 'TT-2': ['GH-2', 'V1'], 'TT-3': ['GH-3', 'V2']} + self.assertEqual(results, expected_results) @mock.patch("wqflask.api.correlation.corr_result_helpers.normalize_values") - def test_get_sample_r_and_p_values(self,mock_normalize): - - group=AttributeSetter({"samplelist":["S1","S2","S3","S4","S5","S6","S7"]}) - target_dataset=AttributeSetter({"group":group}) - - target_vals=[3.4, 6.2, 4.1,3.4,1.2,5.6] - trait_data={"S1":AttributeSetter({"value":2.3}),"S2":AttributeSetter({"value":1.1}),"S3":AttributeSetter({"value":6.3}),"S4":AttributeSetter({"value":3.6}),"S5":AttributeSetter({"value":4.1}),"S6":AttributeSetter({"value":5.0})} - this_trait=AttributeSetter({"data":trait_data}) - mock_normalize.return_value=([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6) - mock_normalize.side_effect=[([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6),([2.3,1.1,6.3,3.6,4.1,5.0], [3.4,6.2,4.1,3.4,1.2,5.6], 6),([2.3,1.1,1.4], [3.4,6.2,4.1], 3)] - - results_pearsonr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") - results_spearmanr=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="spearman") - results_num_overlap=get_sample_r_and_p_values(this_trait=this_trait,this_dataset={},target_vals=target_vals,target_dataset=target_dataset,type="pearson") - expected_pearsonr=[-0.21618688834430866, 0.680771605997119, 6] - expected_spearmanr=[-0.11595420713048969, 0.826848213385815, 6] - for i,val in enumerate(expected_pearsonr): - self.assertAlmostEqual(val,results_pearsonr[i]) - for i,val in enumerate(expected_spearmanr): - self.assertAlmostEqual(val,results_spearmanr[i]) - self.assertEqual(results_num_overlap,None) + def test_get_sample_r_and_p_values(self, mock_normalize): + + group = AttributeSetter( + {"samplelist": ["S1", "S2", "S3", "S4", "S5", "S6", "S7"]}) + target_dataset = AttributeSetter({"group": group}) + + target_vals = [3.4, 6.2, 4.1, 3.4, 1.2, 5.6] + trait_data = {"S1": AttributeSetter({"value": 2.3}), "S2": AttributeSetter({"value": 1.1}), + "S3": AttributeSetter( + {"value": 6.3}), "S4": AttributeSetter({"value": 3.6}), "S5": AttributeSetter({"value": 4.1}), + "S6": AttributeSetter({"value": 5.0})} + this_trait = AttributeSetter({"data": trait_data}) + mock_normalize.return_value = ([2.3, 1.1, 6.3, 3.6, 4.1, 5.0], + [3.4, 6.2, 4.1, 3.4, 1.2, 5.6], 6) + mock_normalize.side_effect = [([2.3, 1.1, 6.3, 3.6, 4.1, 5.0], + [3.4, 6.2, 4.1, 3.4, 1.2, 5.6], 6), + ([2.3, 1.1, 6.3, 3.6, 4.1, 5.0], + [3.4, 6.2, 4.1, 3.4, 1.2, 5.6], 6), + ([2.3, 1.1, 1.4], [3.4, 6.2, 4.1], 3)] + + results_pearsonr = get_sample_r_and_p_values(this_trait=this_trait, this_dataset={ + }, target_vals=target_vals, target_dataset=target_dataset, type="pearson") + results_spearmanr = get_sample_r_and_p_values(this_trait=this_trait, this_dataset={ + }, target_vals=target_vals, target_dataset=target_dataset, type="spearman") + results_num_overlap = get_sample_r_and_p_values(this_trait=this_trait, this_dataset={ + }, target_vals=target_vals, target_dataset=target_dataset, type="pearson") + expected_pearsonr = [-0.21618688834430866, 0.680771605997119, 6] + expected_spearmanr = [-0.11595420713048969, 0.826848213385815, 6] + for i, val in enumerate(expected_pearsonr): + self.assertAlmostEqual(val, results_pearsonr[i],4) + for i, val in enumerate(expected_spearmanr): + self.assertAlmostEqual(val, results_spearmanr[i],4) + self.assertEqual(results_num_overlap, None) @mock.patch("wqflask.api.correlation.do_literature_correlation_for_all_traits") - def test_calculate_results(self,literature_correlation): - - literature_correlation.return_value={'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1]} - - - - this_dataset=MockDataset({"group":AttributeSetter({"species":"rat"})}) - target_dataset=MockDataset({"group":AttributeSetter({"species":"rat"})}) - this_trait=AttributeSetter({"geneid":"GH-1"}) - corr_params={"type":"literature"} - sorted_results=calculate_results(this_trait=this_trait,this_dataset=this_dataset,target_dataset=target_dataset,corr_params=corr_params) - expected_results={'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1], 'TT-1': ['GH-1', 0]} - - self.assertTrue(isinstance(sorted_results,OrderedDict)) - self.assertEqual(dict(sorted_results),expected_results) - - - - - - + def test_calculate_results(self, literature_correlation): + + literature_correlation.return_value = { + 'TT-1': ['GH-1', 0], 'TT-2': ['GH-2', 3], 'TT-3': ['GH-3', 1]} + + this_dataset = MockDataset( + {"group": AttributeSetter({"species": "rat"})}) + target_dataset = MockDataset( + {"group": AttributeSetter({"species": "rat"})}) + this_trait = AttributeSetter({"geneid": "GH-1"}) + corr_params = {"type": "literature"} + sorted_results = calculate_results( + this_trait=this_trait, this_dataset=this_dataset, target_dataset=target_dataset, corr_params=corr_params) + expected_results = {'TT-2': ['GH-2', 3], + 'TT-3': ['GH-3', 1], 'TT-1': ['GH-1', 0]} + + self.assertTrue(isinstance(sorted_results, OrderedDict)) + self.assertEqual(dict(sorted_results), expected_results) -- cgit v1.2.3 From 4773ac8715896489562df9321b4a4d34ae61d6a7 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 20:10:37 +0300 Subject: pep8 formatting in wqflask/api/test_mapping.py --- wqflask/tests/unit/wqflask/api/test_mapping.py | 154 ++++++++++++------------- 1 file changed, 75 insertions(+), 79 deletions(-) diff --git a/wqflask/tests/unit/wqflask/api/test_mapping.py b/wqflask/tests/unit/wqflask/api/test_mapping.py index 5455b215..b094294a 100644 --- a/wqflask/tests/unit/wqflask/api/test_mapping.py +++ b/wqflask/tests/unit/wqflask/api/test_mapping.py @@ -5,108 +5,104 @@ from wqflask.api.mapping import do_mapping_for_api class AttributeSetter: - def __init__(self,obj): - for key,value in obj.items(): - setattr(self,key,value) + def __init__(self, obj): + for key, value in obj.items(): + setattr(self, key, value) + class MockGroup(AttributeSetter): def get_marker(self): - self.markers=[] + self.markers = [] + + class TestMapping(unittest.TestCase): - + def test_initialize_parameters(self): - expected_results={ - "format":"json", - "limit_to":False, - "mapping_method":"gemma", - "maf":0.01, - "use_loco":True, - "num_perm":0, - "perm_check":False + expected_results = { + "format": "json", + "limit_to": False, + "mapping_method": "gemma", + "maf": 0.01, + "use_loco": True, + "num_perm": 0, + "perm_check": False } - results=initialize_parameters(start_vars={},dataset={},this_trait={}) - self.assertEqual(results,expected_results) + results = initialize_parameters( + start_vars={}, dataset={}, this_trait={}) + self.assertEqual(results, expected_results) - start_vars={ - "format":"F1", - "limit_to":"1", - "mapping_method":"rqtl", - "control_marker":True, - "pair_scan":"true", - "interval_mapping":"true", - "use_loco":"true", - "num_perm":"14" + start_vars = { + "format": "F1", + "limit_to": "1", + "mapping_method": "rqtl", + "control_marker": True, + "pair_scan": "true", + "interval_mapping": "true", + "use_loco": "true", + "num_perm": "14" } - results_2=initialize_parameters(start_vars=start_vars,dataset={},this_trait={}) - expected_results={ - "format":"F1", - "limit_to":1, - "mapping_method":"gemma", - "maf":0.01, - "use_loco":True, - "num_perm":14, - "perm_check":"ON" + results_2 = initialize_parameters( + start_vars=start_vars, dataset={}, this_trait={}) + expected_results = { + "format": "F1", + "limit_to": 1, + "mapping_method": "gemma", + "maf": 0.01, + "use_loco": True, + "num_perm": 14, + "perm_check": "ON" } - self.assertEqual(results_2,expected_results) + self.assertEqual(results_2, expected_results) - @mock.patch("wqflask.api.mapping.rqtl_mapping.run_rqtl_geno") @mock.patch("wqflask.api.mapping.gemma_mapping.run_gemma") @mock.patch("wqflask.api.mapping.initialize_parameters") @mock.patch("wqflask.api.mapping.retrieve_sample_data") @mock.patch("wqflask.api.mapping.create_trait") @mock.patch("wqflask.api.mapping.data_set.create_dataset") - def test_do_mapping_for_api(self,mock_create_dataset,mock_trait,mock_retrieve_sample,mock_param,run_gemma - ,run_rqtl_geno): - start_vars={ - "db":"Temp", - "trait_id":"dewf3232rff2", - "format":"F1", - "mapping_method":"gemma", - "use_loco":True + def test_do_mapping_for_api(self, mock_create_dataset, mock_trait, mock_retrieve_sample, mock_param, run_gemma, run_rqtl_geno): + start_vars = { + "db": "Temp", + "trait_id": "dewf3232rff2", + "format": "F1", + "mapping_method": "gemma", + "use_loco": True } - sampleList=["S1","S2","S3","S4"] - samplelist=["S1","S2","S4"] - dataset=AttributeSetter({"group":samplelist}) - this_trait=AttributeSetter({}) - trait_data=AttributeSetter({ - "data":{ - "item1":AttributeSetter({"name":"S1","value":"S1_value"}), - "item2":AttributeSetter({"name":"S2","value":"S2_value"}), - "item3":AttributeSetter({"name":"S3","value":"S3_value"}), + sampleList = ["S1", "S2", "S3", "S4"] + samplelist = ["S1", "S2", "S4"] + dataset = AttributeSetter({"group": samplelist}) + this_trait = AttributeSetter({}) + trait_data = AttributeSetter({ + "data": { + "item1": AttributeSetter({"name": "S1", "value": "S1_value"}), + "item2": AttributeSetter({"name": "S2", "value": "S2_value"}), + "item3": AttributeSetter({"name": "S3", "value": "S3_value"}), } - }) - trait=AttributeSetter({ - "data":trait_data - }) - - dataset.return_value=dataset - mock_trait.return_value=this_trait - - mock_retrieve_sample.return_value=trait - mock_param.return_value={ - "format":"F1", - "limit_to":False, - "mapping_method":"gemma", - "maf":0.01, - "use_loco":"True", - "num_perm":14, - "perm_check":"ON" + }) + trait = AttributeSetter({ + "data": trait_data + }) + + dataset.return_value = dataset + mock_trait.return_value = this_trait + + mock_retrieve_sample.return_value = trait + mock_param.return_value = { + "format": "F1", + "limit_to": False, + "mapping_method": "gemma", + "maf": 0.01, + "use_loco": "True", + "num_perm": 14, + "perm_check": "ON" } - run_gemma.return_value=["results"] - results=do_mapping_for_api(start_vars=start_vars) - self.assertEqual(results,("results",None)) - - - - - - - + run_gemma.return_value = ["results"] + results = do_mapping_for_api(start_vars=start_vars) + self.assertEqual(results, ("results", None)) -- cgit v1.2.3 From 6b6820ec9975ae4c7e9628e0d2b41754b0429b0e Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Wed, 16 Dec 2020 11:29:19 +0300 Subject: modify tests for show_corr_results --- wqflask/tests/unit/wqflask/correlation/__init__.py | 0 .../correlation/test_correlation_functions.py | 3 +- .../wqflask/correlation/test_show_corr_results.py | 174 +++++++++++---------- 3 files changed, 90 insertions(+), 87 deletions(-) create mode 100644 wqflask/tests/unit/wqflask/correlation/__init__.py diff --git a/wqflask/tests/unit/wqflask/correlation/__init__.py b/wqflask/tests/unit/wqflask/correlation/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py index db449eb1..44d2e0fc 100644 --- a/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py +++ b/wqflask/tests/unit/wqflask/correlation/test_correlation_functions.py @@ -5,8 +5,7 @@ from wqflask.correlation.correlation_functions import cal_zero_order_corr_for_ti class TestCorrelationFunctions(unittest.TestCase): - - + @mock.patch("wqflask.correlation.correlation_functions.MrnaAssayTissueData") def test_get_trait_symbol_and_tissue_values(self, mock_class): """test for getting trait symbol and tissue_values""" diff --git a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py index 969a84f5..ffb96dd6 100644 --- a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py +++ b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py @@ -2,92 +2,96 @@ import unittest from unittest import mock from wqflask.correlation.show_corr_results import get_header_fields from wqflask.correlation.show_corr_results import generate_corr_json -from wqflask.correlation.show_corr_results import do_bicor -class Trait: - def __init__(self,trait_obj): - for key,value in trait_obj.items(): - setattr(self,key,value) +class AttributeSetter: + def __init__(self, trait_obj): + for key, value in trait_obj.items(): + setattr(self, key, value) -class TestShowCorrResults(unittest.TestCase): - def test_get_header_fields(self): - expected=[ - ['Index', - 'Record', - 'Symbol', - 'Description', - 'Location', - 'Mean', - 'Sample rho', - 'N', - 'Sample p(rho)', - 'Lit rho', - 'Tissue rho', - 'Tissue p(rho)', - 'Max LRS', - 'Max LRS Location', - 'Additive Effect'], - - ['Index', - 'ID', - 'Location', - 'Sample r', - 'N', - 'Sample p(r)'] - - ] - result1=get_header_fields("ProbeSet","spearman") - result2=get_header_fields("Other","Other") - self.assertEqual(result1,expected[0]) - self.assertEqual(result2,expected[1]) - - - - - def test_generate_corr_json(self): - this_trait=Trait({"name":"trait_test"}) - dataset=Trait({"name":"the_name"}) - target_dataset=Trait({"type":"Publish"}) - - trait_with_publish={ - "description_display":"Trait 2 description", - "authors":"trait_2 ", - "pubmed_id":"34n4nn31hn43", - "lrs_location":"N/A", - "additive":"", - "sample_r":100, - "num_overlap":3.2, - "view":True, - "name":"trait_1", - "pubmed_text":"2016", - "additive":"", - "sample_r":10.5, - "LRS_score_repr":"N/A", - "LRS_location_repr":"N/A", - "sample_p":5, - "num_overlap":"num_1" - - - - } - expected_results="""[{"trait_id": "trait_1", "description": "Trait 2 description", "authors": "trait_2 ", "pubmed_id": "34n4nn31hn43", "year": "2016", "lrs_score": "N/A", "lrs_location": "N/A", "additive": "N/A", "sample_r": "10.500", "num_overlap": "num_1", "sample_p": "5.000e+00"}]""" - - corr_results=[Trait(trait_with_publish)] - results=generate_corr_json(corr_results=corr_results,this_trait=this_trait,dataset=dataset,target_dataset=target_dataset,for_api=True) - self.assertEqual(results,expected_results) - - - - def test_generate_corr_json_view_false(self): - trait=Trait({"view":False}) - corr_results=[trait] - this_trait=Trait({"name":"trait_test"}) - dataset=Trait({"name":"the_name"}) - - - results_where_view_is_false=generate_corr_json(corr_results=corr_results,this_trait=this_trait,dataset={},target_dataset={},for_api=False) - - # self.assertEqual(results,[]) - self.assertEqual(results_where_view_is_false,"[]") \ No newline at end of file +class TestShowCorrResults(unittest.TestCase): + def test_get_header_fields(self): + expected = [ + ['Index', + 'Record', + 'Symbol', + 'Description', + 'Location', + 'Mean', + 'Sample rho', + 'N', + 'Sample p(rho)', + 'Lit rho', + 'Tissue rho', + 'Tissue p(rho)', + 'Max LRS', + 'Max LRS Location', + 'Additive Effect'], + + ['Index', + 'ID', + 'Location', + 'Sample r', + 'N', + 'Sample p(r)'] + + ] + result1 = get_header_fields("ProbeSet", "spearman") + result2 = get_header_fields("Other", "Other") + self.assertEqual(result1, expected[0]) + self.assertEqual(result2, expected[1]) + + @mock.patch("wqflask.correlation.show_corr_results.hmac.data_hmac") + def test_generate_corr_json(self, mock_data_hmac): + mock_data_hmac.return_value = "hajsdiau" + + dataset = AttributeSetter({"name": "the_name"}) + this_trait = AttributeSetter( + {"name": "trait_test", "dataset": dataset}) + target_dataset = AttributeSetter({"type": "Publish"}) + corr_trait_1 = AttributeSetter({ + "name": "trait_1", + "dataset": AttributeSetter({"name": "dataset_1"}), + "view": True, + "abbreviation": "T1", + "description_display": "Trait I description", + "authors": "JM J,JYEW", + "pubmed_id": "34n4nn31hn43", + "pubmed_text": "2016", + "pubmed_link": "https://www.load", + "lod_score": "", + "LRS_location_repr": "BXBS", + "additive": "", + "sample_r": 10.5, + "num_overlap": 2, + "sample_p": 5 + + + + + }) + corr_results = [corr_trait_1] + + dataset_type_other = { + "location": "cx-3-4", + "sample_4": 12.32, + "num_overlap": 3, + "sample_p": 10.34 + } + + expected_results = '[{"index": 1, "trait_id": "trait_1", "dataset": "dataset_1", "hmac": "hajsdiau", "abbreviation_display": "T1", "description": "Trait I description", "authors_display": "JM J,JYEW", "additive": "N/A", "pubmed_id": "34n4nn31hn43", "year": "2016", "lod_score": "N/A", "lrs_location": "BXBS", "sample_r": "10.500", "num_overlap": 2, "sample_p": "5.000e+00"}]' + + results1 = generate_corr_json(corr_results=corr_results, this_trait=this_trait, + dataset=dataset, target_dataset=target_dataset, for_api=True) + self.assertEqual(expected_results, results1) + + def test_generate_corr_json_view_false(self): + trait = AttributeSetter({"view": False}) + corr_results = [trait] + this_trait = AttributeSetter({"name": "trait_test"}) + dataset = AttributeSetter({"name": "the_name"}) + + results_where_view_is_false = generate_corr_json( + corr_results=corr_results, this_trait=this_trait, dataset={}, target_dataset={}, for_api=False) + self.assertEqual(results_where_view_is_false, "[]") -- cgit v1.2.3 From f2e4e893f5639f216f8cc6fc57984aaebffd82ef Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 14:11:23 +0300 Subject: add tests for snp browser --- wqflask/tests/unit/wqflask/snp_browser/__init__.py | 0 .../unit/wqflask/snp_browser/test_snp_browser.py | 84 ++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 wqflask/tests/unit/wqflask/snp_browser/__init__.py create mode 100644 wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py diff --git a/wqflask/tests/unit/wqflask/snp_browser/__init__.py b/wqflask/tests/unit/wqflask/snp_browser/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py new file mode 100644 index 00000000..e8751778 --- /dev/null +++ b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py @@ -0,0 +1,84 @@ +import unittest +from unittest import mock +from wqflask import app +from wqflask.snp_browser.snp_browser import get_gene_id +from wqflask.snp_browser.snp_browser import get_gene_id_name_dict +from wqflask.snp_browser.snp_browser import check_if_in_gene +from wqflask.snp_browser.snp_browser import get_browser_sample_lists +from wqflask.snp_browser.snp_browser import get_header_list + +class TestSnpBrowser(unittest.TestCase): + def setUp(self): + self.app_context = app.app_context() + self.app_context.push() + + def tearDown(self): + self.app_context.pop() + + + @mock.patch("wqflask.snp_browser.snp_browser.g") + def test_get_gene_id(self, mock_db): + mock_db.db.execute.return_value.fetchone.return_value = "517d729f-aa13-4413-a885-40a3f7ff768a" + called_value="\n SELECT\n geneId\n FROM\n GeneList\n WHERE\n SpeciesId = c9c0f59e-1259-4cba-91e6-831ef1a99c83 AND geneSymbol = 'INSR'\n " + results = get_gene_id( + species_id="c9c0f59e-1259-4cba-91e6-831ef1a99c83", gene_name="INSR") + mock_db.db.execute.assert_called_once_with(called_value) + self.assertEqual(results, "517d729f-aa13-4413-a885-40a3f7ff768a") + + @mock.patch("wqflask.snp_browser.snp_browser.g") + def test_gene_id_name_dict(self,mock_db): + no_gene_names=[] + self.assertEqual("",get_gene_id_name_dict(species_id="fregb343bui43g4",gene_name_list=no_gene_names)) + gene_name_list=["GH1","GH2","GH3"] + mock_db.db.execute.return_value.fetchall.side_effect=[[],[("fsdf43-fseferger-f22","GH1"),("1sdf43-fsewferger-f22","GH2"), + ("fwdj43-fstferger-f22","GH3")]] + no_results=get_gene_id_name_dict(species_id="ret3-32rf32",gene_name_list=gene_name_list) + results_found=get_gene_id_name_dict(species_id="ret3-32rf32",gene_name_list=gene_name_list) + expected_found= {'GH1': 'fsdf43-fseferger-f22', 'GH2': '1sdf43-fsewferger-f22', 'GH3': 'fwdj43-fstferger-f22'} + db_query_value="\n SELECT\n geneId, geneSymbol\n FROM\n GeneList\n WHERE\n SpeciesId = ret3-32rf32 AND geneSymbol in ('GH1','GH2','GH3')\n " + mock_db.db.execute.assert_called_with(db_query_value) + self.assertEqual(results_found,expected_found) + self.assertEqual(no_results,{}) + + @mock.patch("wqflask.snp_browser.snp_browser.g") + def test_check_if_in_gene(self,mock_db): + mock_db.db.execute.return_value.fetchone.side_effect=[("fsdf-232sdf-sdf","GHA"),""] + results_found=check_if_in_gene(species_id="517d729f-aa13-4413-a885-40a3f7ff768a",chr="CH1",mb=12.09) + db_query_value="SELECT geneId, geneSymbol\n FROM GeneList\n WHERE SpeciesId = 517d729f-aa13-4413-a885-40a3f7ff768a AND chromosome = 'CH1' AND\n (txStart < 12.09 AND txEnd > 12.09); " + gene_not_found=check_if_in_gene(species_id="517d729f-aa13-4413-a885-40a3f7ff768a",chr="CH1",mb=12.09) + mock_db.db.execute.assert_called_with(db_query_value) + self.assertEqual(gene_not_found,"") + + @mock.patch("wqflask.snp_browser.snp_browser.g") + def test_get_browser_sample_lists(self,mock_db): + mock_db.db.execute.return_value.fetchall.return_value=[] + + results=get_browser_sample_lists(species_id="12") + self.assertEqual(results, {'mouse': [], 'rat': []}) + + def test_get_header_list(self): + empty_columns={"snp_source":"false","conservation_score":"true","gene_name":"false","transcript":"false","exon":"false","domain_2":"true","function":"false","function_details":"true"} + strains={"mouse":["S1","S2","S3","S4","S5"],"rat":[]} + expected_results=([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) + + results_with_snp=get_header_list(variant_type="SNP",strains=strains,species="Mouse",empty_columns=empty_columns) + results_with_indel=get_header_list(variant_type="InDel",strains=strains,species="rat",empty_columns=[]) + expected_results_with_indel=(['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'],0) + + self.assertEqual(expected_results,results_with_snp) + self.assertEqual(results_with_indel,expected_results_with_indel) + + + + + + + + + + + + + + + -- cgit v1.2.3 From db3170eb2fe66d8fd337803a730c18367df1b150 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 16:11:07 +0300 Subject: add tests for type checking --- wqflask/tests/unit/utility/test_type_checking.py | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 wqflask/tests/unit/utility/test_type_checking.py diff --git a/wqflask/tests/unit/utility/test_type_checking.py b/wqflask/tests/unit/utility/test_type_checking.py new file mode 100644 index 00000000..1ea11695 --- /dev/null +++ b/wqflask/tests/unit/utility/test_type_checking.py @@ -0,0 +1,57 @@ +import unittest +from utility.type_checking import is_float +from utility.type_checking import is_int +from utility.type_checking import is_str +from utility.type_checking import get_float +from utility.type_checking import get_int +from utility.type_checking import get_string +class TestTypeChecking(unittest.TestCase): + def test_is_float(self): + floats=[2,1.2,'3.1'] + not_floats=["String",None,[],()] + for flt in floats: + results=is_float(flt) + self.assertTrue(results) + for nflt in not_floats: + results=is_float(nflt) + self.assertFalse(results) + + def test_is_int(self): + int_values=[1,1.1] + not_int_values=["1sdf",None,[],"1.1"] + for int_val in int_values: + results=is_int(int_val) + self.assertTrue(results) + for not_int in not_int_values: + results=is_int(not_int) + self.assertFalse(results) + + def test_is_str(self): + string_values=[1,False,[],{},"string_value"] + falsey_values=[None] + for string_val in string_values: + results=is_str(string_val) + self.assertTrue(results) + for non_string in falsey_values: + results=is_str(non_string) + self.assertFalse(results) + + + def test_get_float(self): + vars_object={"min_value":"12"} + results=get_float(vars_object,"min_value") + self.assertEqual(results,12.0) + + def test_get_int(self): + vars_object={"lx_value":"1"} + results=get_int(vars_object,"lx_value") + self.assertEqual(results,1) + + def test_get_string(self): + string_object={"mx_value":1} + results=get_string(string_object,"mx_value") + self.assertEqual(results,"1") + + + + -- cgit v1.2.3 From 2030cc56db878b05e5507c7c3d5ddef39ff223cb Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 16:15:01 +0300 Subject: replace vars with vars_obj which is a function name in python --- wqflask/utility/type_checking.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/wqflask/utility/type_checking.py b/wqflask/utility/type_checking.py index f15b17e2..6b029317 100644 --- a/wqflask/utility/type_checking.py +++ b/wqflask/utility/type_checking.py @@ -23,20 +23,20 @@ def is_str(value): except: return False -def get_float(vars,name,default=None): - if name in vars: - if is_float(vars[name]): - return float(vars[name]) +def get_float(vars_obj,name,default=None): + if name in vars_obj: + if is_float(vars_obj[name]): + return float(vars_obj[name]) return default -def get_int(vars,name,default=None): - if name in vars: - if is_int(vars[name]): - return float(vars[name]) +def get_int(vars_obj,name,default=None): + if name in vars_obj: + if is_int(vars_obj[name]): + return float(vars_obj[name]) return default -def get_string(vars,name,default=None): - if name in vars: - if not vars[name] is None: - return str(vars[name]) +def get_string(vars_obj,name,default=None): + if name in vars_obj: + if not vars_obj[name] is None: + return str(vars_obj[name]) return default -- cgit v1.2.3 From 868b8cba1cda983d8d401e60e30794529b557c80 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 22:36:36 +0300 Subject: modify get_header tests --- .../unit/wqflask/snp_browser/test_snp_browser.py | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py index e8751778..9ec32c78 100644 --- a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py +++ b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py @@ -15,6 +15,18 @@ class TestSnpBrowser(unittest.TestCase): def tearDown(self): self.app_context.pop() + def test_get_header_list(self): + empty_columns={"snp_source":"false","conservation_score":"true","gene_name":"false","transcript":"false","exon":"false","domain_2":"true","function":"false","function_details":"true"} + strains={"mouse":["S1","S2","S3","S4","S5"],"rat":[]} + expected_results=([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) + + results_with_snp=get_header_list(variant_type="SNP",strains=strains,species="Mouse",empty_columns=empty_columns) + results_with_indel=get_header_list(variant_type="InDel",strains=strains,species="rat",empty_columns=[]) + expected_results_with_indel=(['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'],0) + + self.assertEqual(expected_results,results_with_snp) + self.assertEqual(results_with_indel,expected_results_with_indel) + @mock.patch("wqflask.snp_browser.snp_browser.g") def test_get_gene_id(self, mock_db): @@ -56,17 +68,6 @@ class TestSnpBrowser(unittest.TestCase): results=get_browser_sample_lists(species_id="12") self.assertEqual(results, {'mouse': [], 'rat': []}) - def test_get_header_list(self): - empty_columns={"snp_source":"false","conservation_score":"true","gene_name":"false","transcript":"false","exon":"false","domain_2":"true","function":"false","function_details":"true"} - strains={"mouse":["S1","S2","S3","S4","S5"],"rat":[]} - expected_results=([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) - - results_with_snp=get_header_list(variant_type="SNP",strains=strains,species="Mouse",empty_columns=empty_columns) - results_with_indel=get_header_list(variant_type="InDel",strains=strains,species="rat",empty_columns=[]) - expected_results_with_indel=(['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'],0) - - self.assertEqual(expected_results,results_with_snp) - self.assertEqual(results_with_indel,expected_results_with_indel) -- cgit v1.2.3 From 5a73d56fdbe197e99b476d49d4adce9403c8daeb Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Fri, 18 Dec 2020 15:18:19 +0300 Subject: refactor tests and pep8 formatting --- wqflask/tests/unit/utility/test_type_checking.py | 93 ++++++++-------- .../unit/wqflask/snp_browser/test_snp_browser.py | 120 ++++++++++++--------- 2 files changed, 112 insertions(+), 101 deletions(-) diff --git a/wqflask/tests/unit/utility/test_type_checking.py b/wqflask/tests/unit/utility/test_type_checking.py index 1ea11695..48d110c7 100644 --- a/wqflask/tests/unit/utility/test_type_checking.py +++ b/wqflask/tests/unit/utility/test_type_checking.py @@ -5,53 +5,50 @@ from utility.type_checking import is_str from utility.type_checking import get_float from utility.type_checking import get_int from utility.type_checking import get_string -class TestTypeChecking(unittest.TestCase): - def test_is_float(self): - floats=[2,1.2,'3.1'] - not_floats=["String",None,[],()] - for flt in floats: - results=is_float(flt) - self.assertTrue(results) - for nflt in not_floats: - results=is_float(nflt) - self.assertFalse(results) - - def test_is_int(self): - int_values=[1,1.1] - not_int_values=["1sdf",None,[],"1.1"] - for int_val in int_values: - results=is_int(int_val) - self.assertTrue(results) - for not_int in not_int_values: - results=is_int(not_int) - self.assertFalse(results) - - def test_is_str(self): - string_values=[1,False,[],{},"string_value"] - falsey_values=[None] - for string_val in string_values: - results=is_str(string_val) - self.assertTrue(results) - for non_string in falsey_values: - results=is_str(non_string) - self.assertFalse(results) - - - def test_get_float(self): - vars_object={"min_value":"12"} - results=get_float(vars_object,"min_value") - self.assertEqual(results,12.0) - - def test_get_int(self): - vars_object={"lx_value":"1"} - results=get_int(vars_object,"lx_value") - self.assertEqual(results,1) - - def test_get_string(self): - string_object={"mx_value":1} - results=get_string(string_object,"mx_value") - self.assertEqual(results,"1") - - +class TestTypeChecking(unittest.TestCase): + def test_is_float(self): + floats = [2, 1.2, '3.1'] + not_floats = ["String", None, [], ()] + for flt in floats: + results = is_float(flt) + self.assertTrue(results) + for nflt in not_floats: + results = is_float(nflt) + self.assertFalse(results) + + def test_is_int(self): + int_values = [1, 1.1] + not_int_values = ["string", None, [], "1.1"] + for int_val in int_values: + results = is_int(int_val) + self.assertTrue(results) + for not_int in not_int_values: + results = is_int(not_int) + self.assertFalse(results) + + def test_is_str(self): + string_values = [1, False, [], {}, "string_value"] + falsey_values = [None] + for string_val in string_values: + results = is_str(string_val) + self.assertTrue(results) + for non_string in falsey_values: + results = is_str(non_string) + self.assertFalse(results) + + def test_get_float(self): + vars_object = {"min_value": "12"} + results = get_float(vars_object, "min_value") + self.assertEqual(results, 12.0) + + def test_get_int(self): + vars_object = {"lx_value": "1"} + results = get_int(vars_object, "lx_value") + self.assertEqual(results, 1) + + def test_get_string(self): + string_object = {"mx_value": 1} + results = get_string(string_object, "mx_value") + self.assertEqual(results, "1") \ No newline at end of file diff --git a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py index 9ec32c78..496d228f 100644 --- a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py +++ b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py @@ -7,6 +7,7 @@ from wqflask.snp_browser.snp_browser import check_if_in_gene from wqflask.snp_browser.snp_browser import get_browser_sample_lists from wqflask.snp_browser.snp_browser import get_header_list + class TestSnpBrowser(unittest.TestCase): def setUp(self): self.app_context = app.app_context() @@ -16,70 +17,83 @@ class TestSnpBrowser(unittest.TestCase): self.app_context.pop() def test_get_header_list(self): - empty_columns={"snp_source":"false","conservation_score":"true","gene_name":"false","transcript":"false","exon":"false","domain_2":"true","function":"false","function_details":"true"} - strains={"mouse":["S1","S2","S3","S4","S5"],"rat":[]} - expected_results=([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) - - results_with_snp=get_header_list(variant_type="SNP",strains=strains,species="Mouse",empty_columns=empty_columns) - results_with_indel=get_header_list(variant_type="InDel",strains=strains,species="rat",empty_columns=[]) - expected_results_with_indel=(['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'],0) - - self.assertEqual(expected_results,results_with_snp) - self.assertEqual(results_with_indel,expected_results_with_indel) - + empty_columns = {"snp_source": "false", "conservation_score": "true", "gene_name": "false", + "transcript": "false", "exon": "false", "domain_2": "true", "function": "false", "function_details": "true"} + strains = {"mouse": ["S1", "S2", "S3", "S4", "S5"], "rat": []} + expected_results = ([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', + 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) + + results_with_snp = get_header_list( + variant_type="SNP", strains=strains, species="Mouse", empty_columns=empty_columns) + results_with_indel = get_header_list( + variant_type="InDel", strains=strains, species="rat", empty_columns=[]) + expected_results_with_indel = ( + ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', + 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'], 0) + + self.assertEqual(expected_results, results_with_snp) + self.assertEqual(results_with_indel, expected_results_with_indel) @mock.patch("wqflask.snp_browser.snp_browser.g") def test_get_gene_id(self, mock_db): mock_db.db.execute.return_value.fetchone.return_value = "517d729f-aa13-4413-a885-40a3f7ff768a" - called_value="\n SELECT\n geneId\n FROM\n GeneList\n WHERE\n SpeciesId = c9c0f59e-1259-4cba-91e6-831ef1a99c83 AND geneSymbol = 'INSR'\n " + db_query_value = """ + SELECT + geneId + FROM + GeneList + WHERE + SpeciesId = c9c0f59e-1259-4cba-91e6-831ef1a99c83 AND geneSymbol = 'INSR' + """ results = get_gene_id( species_id="c9c0f59e-1259-4cba-91e6-831ef1a99c83", gene_name="INSR") - mock_db.db.execute.assert_called_once_with(called_value) + mock_db.db.execute.assert_called_once_with(db_query_value) self.assertEqual(results, "517d729f-aa13-4413-a885-40a3f7ff768a") @mock.patch("wqflask.snp_browser.snp_browser.g") - def test_gene_id_name_dict(self,mock_db): - no_gene_names=[] - self.assertEqual("",get_gene_id_name_dict(species_id="fregb343bui43g4",gene_name_list=no_gene_names)) - gene_name_list=["GH1","GH2","GH3"] - mock_db.db.execute.return_value.fetchall.side_effect=[[],[("fsdf43-fseferger-f22","GH1"),("1sdf43-fsewferger-f22","GH2"), - ("fwdj43-fstferger-f22","GH3")]] - no_results=get_gene_id_name_dict(species_id="ret3-32rf32",gene_name_list=gene_name_list) - results_found=get_gene_id_name_dict(species_id="ret3-32rf32",gene_name_list=gene_name_list) - expected_found= {'GH1': 'fsdf43-fseferger-f22', 'GH2': '1sdf43-fsewferger-f22', 'GH3': 'fwdj43-fstferger-f22'} - db_query_value="\n SELECT\n geneId, geneSymbol\n FROM\n GeneList\n WHERE\n SpeciesId = ret3-32rf32 AND geneSymbol in ('GH1','GH2','GH3')\n " - mock_db.db.execute.assert_called_with(db_query_value) - self.assertEqual(results_found,expected_found) - self.assertEqual(no_results,{}) + def test_gene_id_name_dict(self, mock_db): + no_gene_names = [] + self.assertEqual("", get_gene_id_name_dict( + species_id="fregb343bui43g4", gene_name_list=no_gene_names)) + gene_name_list = ["GH1", "GH2", "GH3"] + mock_db.db.execute.return_value.fetchall.side_effect = [[], [("fsdf43-fseferger-f22", "GH1"), ("1sdf43-fsewferger-f22", "GH2"), + ("fwdj43-fstferger-f22", "GH3")]] + no_results = get_gene_id_name_dict( + species_id="ret3-32rf32", gene_name_list=gene_name_list) + results_found = get_gene_id_name_dict( + species_id="ret3-32rf32", gene_name_list=gene_name_list) + expected_found = {'GH1': 'fsdf43-fseferger-f22', + 'GH2': '1sdf43-fsewferger-f22', 'GH3': 'fwdj43-fstferger-f22'} + db_query_value = """ + SELECT + geneId, geneSymbol + FROM + GeneList + WHERE + SpeciesId = ret3-32rf32 AND geneSymbol in ('GH1','GH2','GH3') + """ + mock_db.db.execute.assert_called_with(db_query_value) + self.assertEqual(results_found, expected_found) + self.assertEqual(no_results, {}) @mock.patch("wqflask.snp_browser.snp_browser.g") - def test_check_if_in_gene(self,mock_db): - mock_db.db.execute.return_value.fetchone.side_effect=[("fsdf-232sdf-sdf","GHA"),""] - results_found=check_if_in_gene(species_id="517d729f-aa13-4413-a885-40a3f7ff768a",chr="CH1",mb=12.09) - db_query_value="SELECT geneId, geneSymbol\n FROM GeneList\n WHERE SpeciesId = 517d729f-aa13-4413-a885-40a3f7ff768a AND chromosome = 'CH1' AND\n (txStart < 12.09 AND txEnd > 12.09); " - gene_not_found=check_if_in_gene(species_id="517d729f-aa13-4413-a885-40a3f7ff768a",chr="CH1",mb=12.09) - mock_db.db.execute.assert_called_with(db_query_value) - self.assertEqual(gene_not_found,"") + def test_check_if_in_gene(self, mock_db): + mock_db.db.execute.return_value.fetchone.side_effect = [ + ("fsdf-232sdf-sdf", "GHA"), ""] + results_found = check_if_in_gene( + species_id="517d729f-aa13-4413-a885-40a3f7ff768a", chr="CH1", mb=12.09) + db_query_value = """SELECT geneId, geneSymbol + FROM GeneList + WHERE SpeciesId = 517d729f-aa13-4413-a885-40a3f7ff768a AND chromosome = 'CH1' AND + (txStart < 12.09 AND txEnd > 12.09); """ + gene_not_found = check_if_in_gene( + species_id="517d729f-aa13-4413-a885-40a3f7ff768a", chr="CH1", mb=12.09) + mock_db.db.execute.assert_called_with(db_query_value) + self.assertEqual(gene_not_found, "") @mock.patch("wqflask.snp_browser.snp_browser.g") - def test_get_browser_sample_lists(self,mock_db): - mock_db.db.execute.return_value.fetchall.return_value=[] - - results=get_browser_sample_lists(species_id="12") - self.assertEqual(results, {'mouse': [], 'rat': []}) - - - - - - - - - - - - - - - + def test_get_browser_sample_lists(self, mock_db): + mock_db.db.execute.return_value.fetchall.return_value = [] + results = get_browser_sample_lists(species_id="12") + self.assertEqual(results, {'mouse': [], 'rat': []}) -- cgit v1.2.3 From 47d6c4d9c39b8a506f65ce86a11ff394be76f3d0 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Thu, 17 Dec 2020 20:59:54 +0300 Subject: replace scroller/css/scroller.dataTables.min.css with scrollerStyle/css/scroller.dataTables.min.css --- wqflask/wqflask/templates/search_result_page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 765c4ab8..411a6628 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -3,7 +3,7 @@ {% block css %} <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/font-awesome.min.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/scroller/css/scroller.dataTables.min.css') }}"> + <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/scrollerStyle/css/scroller.dataTables.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}"> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"> <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> -- cgit v1.2.3 From 6781bda17452ee5b948fd0deb217df464a4a7202 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Thu, 17 Dec 2020 21:12:26 +0300 Subject: add scroller.dataTables.min.css and dataTables.scroller.min.js to mechanical rob --- test/requests/link_checker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index bc3b5861..f162ec84 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -103,9 +103,9 @@ def check_packaged_js_files(args_obj, parser): "/js/DataTablesExtensions/colResize/dataTables.colResize.js", "/js/DataTablesExtensions/colReorder/js/dataTables.colReorder.js", "/js/DataTablesExtensions/buttons/js/buttons.colVis.min.js", - "/js/DataTablesExtensions/scroller/js/scroller.dataTables.min.js", + "/js/DataTablesExtensions/scroller/js/dataTables.scroller.min.js", "/js/DataTables/js/jquery.dataTables.js", - "/css/DataTablesExtensions/scroller/css/scroller.dataTables.min.css", + "/js/DataTablesExtensions/scrollerStyle/css/scroller.dataTables.min.css", # Datatables plugins: "/js/DataTablesExtensions/plugins/sorting/natural.js", "/js/DataTablesExtensions/plugins/sorting/scientific.js", -- cgit v1.2.3 From b605f52440e84909631b6afdf510a9e513260901 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Wed, 6 Jan 2021 08:21:44 +0300 Subject: fix tests for show_corr_results --- wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py index ffb96dd6..33601990 100644 --- a/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py +++ b/wqflask/tests/unit/wqflask/correlation/test_show_corr_results.py @@ -61,6 +61,7 @@ class TestShowCorrResults(unittest.TestCase): "pubmed_text": "2016", "pubmed_link": "https://www.load", "lod_score": "", + "mean": "", "LRS_location_repr": "BXBS", "additive": "", "sample_r": 10.5, @@ -80,7 +81,7 @@ class TestShowCorrResults(unittest.TestCase): "sample_p": 10.34 } - expected_results = '[{"index": 1, "trait_id": "trait_1", "dataset": "dataset_1", "hmac": "hajsdiau", "abbreviation_display": "T1", "description": "Trait I description", "authors_display": "JM J,JYEW", "additive": "N/A", "pubmed_id": "34n4nn31hn43", "year": "2016", "lod_score": "N/A", "lrs_location": "BXBS", "sample_r": "10.500", "num_overlap": 2, "sample_p": "5.000e+00"}]' + expected_results = '[{"index": 1, "trait_id": "trait_1", "dataset": "dataset_1", "hmac": "hajsdiau", "abbreviation_display": "T1", "description": "Trait I description", "mean": "N/A", "authors_display": "JM J,JYEW", "additive": "N/A", "pubmed_id": "34n4nn31hn43", "year": "2016", "lod_score": "N/A", "lrs_location": "BXBS", "sample_r": "10.500", "num_overlap": 2, "sample_p": "5.000e+00"}]' results1 = generate_corr_json(corr_results=corr_results, this_trait=this_trait, dataset=dataset, target_dataset=target_dataset, for_api=True) -- cgit v1.2.3 From 4203e9609dcf59fa7369e9e0dde02d0da3c8e32f Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Wed, 6 Jan 2021 08:50:30 +0300 Subject: update tests for snp_browser --- .../tests/unit/wqflask/snp_browser/test_snp_browser.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py index 496d228f..7fa96dba 100644 --- a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py +++ b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py @@ -21,18 +21,25 @@ class TestSnpBrowser(unittest.TestCase): "transcript": "false", "exon": "false", "domain_2": "true", "function": "false", "function_details": "true"} strains = {"mouse": ["S1", "S2", "S3", "S4", "S5"], "rat": []} expected_results = ([['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'ConScore', - 'Domain 1', 'Domain 2', 'Details'], ['S1', 'S2', 'S3', 'S4', 'S5']], 5) + 'Domain 1', 'Domain 2', 'Details'], + ['S1', 'S2', 'S3', 'S4', 'S5']], 5, + ['index', 'snp_name', 'chr', 'mb_formatted', 'alleles', + 'conservation_score', 'domain_1', 'domain_2', + 'function_details', 'S1', 'S2', 'S3', 'S4', 'S5']) results_with_snp = get_header_list( variant_type="SNP", strains=strains, species="Mouse", empty_columns=empty_columns) results_with_indel = get_header_list( variant_type="InDel", strains=strains, species="rat", empty_columns=[]) expected_results_with_indel = ( - ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', - 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'], 0) + ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', + 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'], 0, + ['index', 'indel_name', 'indel_type', 'indel_chr', 'indel_mb_s', + 'indel_mb_e', 'indel_strand', 'indel_size', 'indel_sequence', 'source_name']) self.assertEqual(expected_results, results_with_snp) - self.assertEqual(results_with_indel, expected_results_with_indel) + # self.assertEqual(results_with_indel, expected_results_with_indel) + self.assertEqual(expected_results_with_indel, results_with_indel) @mock.patch("wqflask.snp_browser.snp_browser.g") def test_get_gene_id(self, mock_db): -- cgit v1.2.3 From e55aa51937abf03897a20a52dd7dbf3cfc4ac6c8 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Wed, 6 Jan 2021 08:54:47 +0300 Subject: remove comments --- wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py | 1 - 1 file changed, 1 deletion(-) diff --git a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py index 7fa96dba..ce3e7b83 100644 --- a/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py +++ b/wqflask/tests/unit/wqflask/snp_browser/test_snp_browser.py @@ -38,7 +38,6 @@ class TestSnpBrowser(unittest.TestCase): 'indel_mb_e', 'indel_strand', 'indel_size', 'indel_sequence', 'source_name']) self.assertEqual(expected_results, results_with_snp) - # self.assertEqual(results_with_indel, expected_results_with_indel) self.assertEqual(expected_results_with_indel, results_with_indel) @mock.patch("wqflask.snp_browser.snp_browser.g") -- cgit v1.2.3 From 7bcc5d1e8111d7c74299c7f017c4a0427f8b4830 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 6 Jan 2021 11:51:01 -0600 Subject: Changes to the way R/qtl deals with 4-way crosses so it will work with new HET3-ITP genotypes --- wqflask/wqflask/marker_regression/rqtl_mapping.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py index 0a5758af..4117a0e5 100644 --- a/wqflask/wqflask/marker_regression/rqtl_mapping.py +++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py @@ -94,9 +94,6 @@ def run_rqtl_geno(vals, samples, dataset, mapping_scale, method, model, permChec ro.r('all_covars <- cbind(marker_covars, trait_covars)') else: ro.r('all_covars <- marker_covars') - #logger.info("Saving"); - #ro.r('save.image(file = "/home/dannya/gn2-danny/cross.RData")') - #logger.info("Saving Done"); covars = ro.r['all_covars'] #DEBUG to save the session object to file if pair_scan: @@ -159,7 +156,7 @@ def generate_cross_from_geno(dataset, scale_units): # TODO: Need to figur toskip = which(unlist(lapply(header, function(x){ length(grep("Chr\t", x)) })) == 1)-1 # Major hack to skip the geno headers type <- getGenoCode(header, 'type') if(type == '4-way'){ - genocodes <- c('1','2','3','4') + genocodes <- NULL } else { genocodes <- c(getGenoCode(header, 'mat'), getGenoCode(header, 'het'), getGenoCode(header, 'pat')) # Get the genotype codes } @@ -174,7 +171,7 @@ def generate_cross_from_geno(dataset, scale_units): # TODO: Need to figur require(qtl) if(type == '4-way'){ cat('Loading in as 4-WAY\n') - cross = read.cross(file=out, 'csvr', genotypes=genocodes, crosstype="4way", convertXdata=FALSE) # Load the created cross file using R/qtl read.cross + cross = read.cross(file=out, 'csvr', genotypes=NULL, crosstype="4way") # Load the created cross file using R/qtl read.cross }else if(type == 'f2'){ cat('Loading in as F2\n') cross = read.cross(file=out, 'csvr', genotypes=genocodes, crosstype="f2") # Load the created cross file using R/qtl read.cross @@ -332,8 +329,6 @@ def add_cofactors(cross, this_dataset, covariates, samples): covar_name_string += '"' + col_name + '", ' else: covar_name_string += '"' + col_name + '"' - - logger.info("covar_name_string:" + covar_name_string) else: col_name = "covar_" + str(i) cross = add_phenotype(cross, covar_as_string, col_name) @@ -343,7 +338,6 @@ def add_cofactors(cross, this_dataset, covariates, samples): covar_name_string += '"' + col_name + '"' covar_name_string += ")" - logger.info("covar_name_string:" + covar_name_string); covars_ob = pull_var("trait_covars", cross, covar_name_string) return cross, covars_ob -- cgit v1.2.3 From f617bca3f5298454f8944205f84ae77e0c59ca4b Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 6 Jan 2021 11:53:04 -0600 Subject: Added line to views.py to fixes error if the genotype file contains samples not listed in the DB --- wqflask/wqflask/views.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index c136711e..6b706b3f 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -643,8 +643,9 @@ def loading_page(): samples = genofile_samples for sample in samples: - if sample_vals_dict[sample] != "x": - n_samples += 1 + if sample in sample_vals_dict: + if sample_vals_dict[sample] != "x": + n_samples += 1 start_vars['n_samples'] = n_samples start_vars['wanted_inputs'] = initial_start_vars['wanted_inputs'] @@ -749,10 +750,9 @@ def mapping_results_page(): rendered_template = render_template("mapping_error.html") return rendered_template except: - rendered_template = render_template("mapping_error.html") - return rendered_template + rendered_template = render_template("mapping_error.html") + return rendered_template - #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=" ") -- cgit v1.2.3 From 6c63b869d047daca44ff5facee44833f52b0d861 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 11 Jan 2021 13:49:04 -0600 Subject: Added something to line accounting for certain BXD individual groups when building the correlation drop-down --- wqflask/wqflask/show_trait/show_trait.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 4c6dd005..9b4a8fa4 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -372,7 +372,7 @@ class ShowTrait(object): # We're checking a string here! assert isinstance(this_group, str), "We need a string type thing here" - if this_group[:3] == 'BXD' and this_group != "BXD-Longevity": + if this_group[:3] == 'BXD' and this_group != "BXD-Longevity" and this_group != "BXD-AE": this_group = 'BXD' if this_group: -- cgit v1.2.3 From 2016470a13945e6bb833d28583de9e0877fe91eb Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 11 Jan 2021 14:21:47 -0600 Subject: Fixed error with JS that adds text to footer showing how long it took to render the page --- wqflask/wqflask/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index e368a4be..facebdff 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -264,7 +264,7 @@ {% endblock %} <script type="text/javascript"> - $(window).load(function() { + document.addEventListener('DOMContentLoaded', function() { let timeToLoad = document.createElement("p"); timeToLoad.innerHTML = "It took your browser " + ((Date.now() - pageLoadStart)/1000) + " second(s) to render this page"; document.querySelector("footer .row .col-xs-6").appendChild(timeToLoad); -- cgit v1.2.3 From 3c0715dc52dc583d8a84907a9ba41a799ed3068a Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 12 Jan 2021 11:09:11 -0600 Subject: Added a line that redraws the DataTable, which fixes its initial scroll height --- wqflask/wqflask/templates/search_result_page.html | 37 ++++++----------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 411a6628..5fe65c00 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -146,6 +146,7 @@ <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/scroller/2.0.2/js/dataTables.scroller.min.js"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> @@ -383,36 +384,16 @@ }{% endif %} ], "order": [[1, "asc" ]], - {% if dataset.type != 'Geno' %} - buttons: [ - { - extend: 'columnsToggle', - columns: function( idx, data, node ) { - if (idx != 0) { - return true; - } else { - return false; - } - }, - postfixButtons: [ 'colvisRestore' ] - } - ], - 'sDom': "Bpitirp", - {% else %} - 'sDom': "pitirp", - {% endif %} - 'iDisplayLength': 500, - 'deferRender': true, - 'paging': true, - 'orderClasses': true, - 'processing': true, - 'bServerSide': true, - 'sAjaxSource': '/search_table'+getParams(window.location.href), - 'infoCallback': function(settings, start, end, max, total, pre) { - return "Showing " + start + " to " + (start + this.api().data().length - 1) + " of " + total + " entries"; - } + 'sDom': "itir", + "autoWidth": true, + "bSortClasses": false, + "scrollY": "100vh", + "scroller": true, + "scrollCollapse": true } ); + trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load + $('.toggle-vis').on( 'click', function (e) { e.preventDefault(); -- cgit v1.2.3 From b3aba44e452fbfeb9f79c91f94b00061057937a4 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 12 Jan 2021 17:51:06 -0600 Subject: Fixed issue causing interval mapping to not be displayed correctly --- wqflask/wqflask/marker_regression/run_mapping.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 891fcc66..38f8c26d 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -138,15 +138,15 @@ class RunMapping(object): mapping_results_filename = self.dataset.group.name + "_" + ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6)) self.mapping_results_path = "{}{}.csv".format(webqtlConfig.GENERATED_IMAGE_DIR, mapping_results_filename) - if start_vars['manhattan_plot']: - self.color_scheme = "alternating" - if "color_scheme" in start_vars: - self.color_scheme = start_vars['color_scheme'] - if self.color_scheme == "single": - self.manhattan_single_color = start_vars['manhattan_single_color'] - self.manhattan_plot = True - else: - self.manhattan_plot = False + self.manhattan_plot = False + if 'manhattan_plot' in start_vars: + if start_vars['manhattan_plot'].lower() != "false": + self.color_scheme = "alternating" + if "color_scheme" in start_vars: + self.color_scheme = start_vars['color_scheme'] + if self.color_scheme == "single": + self.manhattan_single_color = start_vars['manhattan_single_color'] + self.manhattan_plot = True self.maf = start_vars['maf'] # Minor allele frequency if "use_loco" in start_vars: -- cgit v1.2.3 From 7d97698ca88460c2f66b67ada31085b02cbc9ee4 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 12 Jan 2021 17:56:52 -0600 Subject: Fixed a bunch fo remaining issues with positioning legend items on the right side of the mapping figure --- .../marker_regression/display_mapping_results.py | 87 +++++++++++----------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 9f778160..bba08f63 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -860,7 +860,10 @@ class DisplayMappingResults(object): text='%2.1f'%item, font=bootScaleFont, fill=BLACK) if self.legendChecked: - startPosY = 30 + if hasattr(self.traitList[0], 'chr') and hasattr(self.traitList[0], 'mb'): + startPosY = 30 + else: + startPosY = 15 smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) leftOffset = canvas.size[0] - xRightOffset - 190 im_drawer.rectangle( @@ -942,28 +945,6 @@ class DisplayMappingResults(object): draw_open_polygon(canvas, xy=traitPixel, outline=BLACK, fill=self.TRANSCRIPT_LOCATION_COLOR) - if self.legendChecked: - startPosY = 15 - nCol = 2 - smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) - if self.manhattan_plot: - leftOffset = xLeftOffset - else: - leftOffset = xLeftOffset+(nCol-1)*200*fontZoom - draw_open_polygon( - canvas, - xy=( - (leftOffset+7, startPosY-7), - (leftOffset, startPosY+7), - (leftOffset+14, startPosY+7)), - outline=BLACK, fill=self.TRANSCRIPT_LOCATION_COLOR - ) - TEXT_Y_DISPLACEMENT = -8 - im_drawer.text( - text="Sequence Site", - xy=(leftOffset+15, startPosY+TEXT_Y_DISPLACEMENT), font=smallLabelFont, - fill=self.TOP_RIGHT_INFO_COLOR) - def drawSNPTrackNew(self, canvas, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): im_drawer = ImageDraw.Draw(canvas) if self.plotScale != 'physic' or self.selectedChr == -1 or not self.diffCol: @@ -1060,17 +1041,38 @@ class DisplayMappingResults(object): labelFont=ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) startPosY = 15 stepPosY = 12*fontZoom + + startPosX = canvas.size[0] - xRightOffset - 415 + if hasattr(self.traitList[0], 'chr') and hasattr(self.traitList[0], 'mb'): + startPosY = 15 + nCol = 2 + smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) + + leftOffset = canvas.size[0] - xRightOffset - 190 + draw_open_polygon( + canvas, + xy=( + (leftOffset + 6, startPosY-7), + (leftOffset - 1, startPosY+7), + (leftOffset + 13, startPosY+7)), + outline=BLACK, fill=self.TRANSCRIPT_LOCATION_COLOR + ) + TEXT_Y_DISPLACEMENT = -8 + im_drawer.text( + text="Sequence Site", + xy=(leftOffset + 20, startPosY+TEXT_Y_DISPLACEMENT), font=smallLabelFont, + fill=self.TOP_RIGHT_INFO_COLOR) + if self.manhattan_plot != True: im_drawer.line( - xy=((xLeftOffset, startPosY), (xLeftOffset+32, startPosY)), + xy=((startPosX, startPosY), (startPosX+32, startPosY)), fill=self.LRS_COLOR, width=2) im_drawer.text( - text=self.LRS_LOD, xy=(xLeftOffset+40, startPosY+TEXT_Y_DISPLACEMENT), + text=self.LRS_LOD, xy=(startPosX+40, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) startPosY += stepPosY if self.additiveChecked: - startPosX = canvas.size[0] - xRightOffset - 400 im_drawer.line( xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.ADDITIVE_COLOR_POSITIVE, width=2) @@ -1080,10 +1082,9 @@ class DisplayMappingResults(object): im_drawer.text( text='Additive Effect', xy=(startPosX+40, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) + startPosY += stepPosY if self.genotype.type == 'intercross' and self.dominanceChecked: - startPosX = canvas.size[0] - xRightOffset - 400 - startPosY += stepPosY im_drawer.line( xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.DOMINANCE_COLOR_POSITIVE, width=4) @@ -1093,44 +1094,42 @@ class DisplayMappingResults(object): im_drawer.text( text='Dominance Effect', xy=(startPosX+42, startPosY+5), font=labelFont, fill=BLACK) + startPosY += stepPosY if self.haplotypeAnalystChecked: - startPosY += stepPosY - startPosX = canvas.size[0] - xRightOffset - 400 im_drawer.line( - xy=((startPosX, startPosY), (startPosX+17, startPosY)), + xy=((startPosX-34, startPosY), (startPosX-17, startPosY)), fill=self.HAPLOTYPE_POSITIVE, width=4) im_drawer.line( - xy=((startPosX+18, startPosY), (startPosX+35, startPosY)), + xy=((startPosX-17, startPosY), (startPosX, startPosY)), fill=self.HAPLOTYPE_NEGATIVE, width=4) im_drawer.line( - xy=((startPosX+36, startPosY), (startPosX+53, startPosY)), + xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.HAPLOTYPE_HETEROZYGOUS, width=4) im_drawer.line( - xy=((startPosX+54, startPosY), (startPosX+67, startPosY)), + xy=((startPosX+17, startPosY), (startPosX+34, startPosY)), fill=self.HAPLOTYPE_RECOMBINATION, width=4) im_drawer.text( text='Haplotypes (Pat, Mat, Het, Unk)', - xy=(startPosX+76, startPosY+5), font=labelFont, fill=BLACK) + xy=(startPosX+41, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) + startPosY += stepPosY if self.permChecked and self.nperm > 0: - startPosY += stepPosY - if self.bootChecked and not self.multipleInterval: - startPosX = canvas.size[0] - xRightOffset - 400 - else: - startPosX = canvas.size[0] - xRightOffset - 190 + thisStartX = startPosX + if self.multipleInterval and not self.bootChecked: + thisStartX = canvas.size[0] - xRightOffset - 205 im_drawer.line( - xy=((startPosX, startPosY), ( startPosX + 32, startPosY)), + xy=((thisStartX, startPosY), ( startPosX + 32, startPosY)), fill=self.SIGNIFICANT_COLOR, width=self.SIGNIFICANT_WIDTH) im_drawer.line( - xy=((startPosX, startPosY + stepPosY), ( startPosX + 32, startPosY + stepPosY)), + xy=((thisStartX, startPosY + stepPosY), ( startPosX + 32, startPosY + stepPosY)), fill=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH) im_drawer.text( text='Significant %s = %2.2f' % (self.LRS_LOD, self.significant), - xy=(startPosX+42, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) + xy=(thisStartX+40, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) im_drawer.text( text='Suggestive %s = %2.2f' % (self.LRS_LOD, self.suggestive), - xy=(startPosX+42, startPosY + TEXT_Y_DISPLACEMENT +stepPosY), font=labelFont, + xy=(thisStartX+40, startPosY + TEXT_Y_DISPLACEMENT +stepPosY), font=labelFont, fill=BLACK) labelFont = ImageFont.truetype(font=VERDANA_FILE, size=12*fontZoom) -- cgit v1.2.3 From 4e8a9dfabf3580f1dd2cfeaa407bae726e7659a0 Mon Sep 17 00:00:00 2001 From: robwwilliams Date: Wed, 13 Jan 2021 11:56:32 -0600 Subject: Just some tweaks to first paragrfaph --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cd35defb..bfb16ddb 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,12 @@ # GeneNetwork -This repository contains the source code for the GeneNetwork (GN) -server http://gn2.genenetwork.org/ (version 2 aka GN2). GN is a Web -2.0 style framework with included tools for doing genetics online -using high-throughput data. GN is used for a wide range of studies. An -exhaustive list of publications mentioning GN and its previous -incarnation WebQTL can be found -[here](http://www.genenetwork.org/reference.html). +This repository contains the current source code for GeneNetwork (GN) +(https://www.genenetwork.org/ (version 2). GN2 is a Web +2.0-style framework that includes data and computational tools for online genetics and genomic analysis of +many different populations and many types of molecular, cellular, and physiological data. +The system is used by scientists and clinians in the field of precision health care and systems genetics. +GN and its predecessors have been in operation since Jan 1994, making it one of the longest-lived web services in biomedical research (https://en.wikipedia.org/wiki/GeneNetwork, and see a partial list of publications using GN and its predecessor, WebQTL (https://genenetwork.org/references/). ## Install -- cgit v1.2.3 From ac28594a4eba9c73b836170ef81beb93f40a11d6 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 13 Jan 2021 14:18:02 -0600 Subject: The Scroller CSS was removed because it forces all row text onto one line; Scroller still seems to function fine without it, which is a little strange --- wqflask/wqflask/templates/search_result_page.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 5fe65c00..b8f89121 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -3,7 +3,6 @@ {% block css %} <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/font-awesome.min.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/scrollerStyle/css/scroller.dataTables.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}"> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"> <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> @@ -125,7 +124,7 @@ {% endif %} </div> {% endif %} - <div id="table_container" {% if dataset.type == 'ProbeSet' or dataset.type == 'Publish' %}style="min-width: 1500px;"{% endif %}> + <div id="table_container" {% if dataset.type == 'ProbeSet' or dataset.type == 'Publish' %}style="min-width: 1500px; max-width:100%;"{% endif %}> <table class="table-hover table-striped cell-border" id='trait_table' style="float: left; width: {% if dataset.type == 'Geno' %}380px{% else %}100%{% endif %};"> <tbody> <td colspan="100%" align="center"><br><b><font size="15">Loading...</font></b><br></td> @@ -310,7 +309,6 @@ { 'title': "Description", 'type': "natural", - 'width': "500px", 'data': null, 'render': function(data, type, row, meta) { try { -- cgit v1.2.3 From 4a67b437215b04a089449f93cfa9ebcaed5640dd Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 14 Jan 2021 14:22:02 -0600 Subject: Re-added some code that was accidentally removed that was needed for adding cofactors to mapping --- wqflask/wqflask/static/new/javascript/show_trait.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 2ec9d6d5..1c8e328d 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -95,6 +95,14 @@ $('#add_to_collection').click(add); sample_lists = js_data.sample_lists; sample_group_types = js_data.sample_group_types; +$(".select_covariates").click(function () { + open_covariate_selection(); +}); +$(".remove_covariates").click(function () { + $("input[name=covariates]").val("") + $(".selected-covariates").val("") +}); + open_trait_selection = function() { return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) { return function() { -- cgit v1.2.3 From aa5d3d6bfedd7df8c6e35465d60bba1c11c8fa79 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 14 Jan 2021 14:22:47 -0600 Subject: Added transform text to mapping figure and fixed an issue where cofactors weren't appearing in the metadata --- .../marker_regression/display_mapping_results.py | 46 +++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 9f1b050d..0de9b9a1 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -636,7 +636,7 @@ class DisplayMappingResults(object): btminfo.append(HtmlGenWrapper.create_br_tag()) btminfo.append('Mapping using genotype data as a trait will result in infinity LRS at one locus. In order to display the result properly, all LRSs higher than 100 are capped at 100.') - def plotIntMapping(self, canvas, offset= (80, 120, 20, 100), zoom = 1, startMb = None, endMb = None, showLocusForm = ""): + def plotIntMapping(self, canvas, offset= (80, 120, 90, 100), zoom = 1, startMb = None, endMb = None, showLocusForm = ""): im_drawer = ImageDraw.Draw(canvas) #calculating margins xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset @@ -644,10 +644,11 @@ class DisplayMappingResults(object): yTopOffset = max(90, yTopOffset) else: if self.legendChecked: + yTopOffset += 10 if self.covariates != "" and self.controlLocus and self.doControl != "false": - yTopOffset = max(120, yTopOffset) - else: - yTopOffset = max(100, yTopOffset) + yTopOffset += 20 + if len(self.transform) > 0: + yTopOffset += 5 else: pass @@ -1131,6 +1132,7 @@ class DisplayMappingResults(object): labelFont = ImageFont.truetype(font=VERDANA_FILE, size=12*fontZoom) labelColor = BLACK + if self.dataset.type == "Publish" or self.dataset.type == "Geno": dataset_label = self.dataset.fullname else: @@ -1172,6 +1174,7 @@ class DisplayMappingResults(object): else: string3 += 'no control for other QTLs' + y_constant = 10 if self.this_trait.name: if self.selectedChr == -1: identification = "Mapping on All Chromosomes for " @@ -1197,23 +1200,48 @@ class DisplayMappingResults(object): im_drawer.textsize(string2, font=labelFont)[0]) im_drawer.text( text=identification, - xy=(canvas.size[0] - xRightOffset-d, 20*fontZoom), font=labelFont, + xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), font=labelFont, fill=labelColor) + y_constant += 15 else: d = 4+ max( im_drawer.textsize(string1, font=labelFont)[0], im_drawer.textsize(string2, font=labelFont)[0]) + + if len(self.transform) > 0: + transform_text = "Transform - " + if self.transform == "qnorm": + transform_text += "Quantile Normalized" + elif self.transform == "log2" or self.transform == "log10": + transform_text += self.transform.capitalize() + elif self.transform == "sqrt": + transform_text += "Square Root" + elif self.transform == "zscore": + transform_text += "Z-Score" + elif self.transform == "invert": + transform_text += "Invert +/-" + + im_drawer.text( + text=transform_text, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), + font=labelFont, fill=labelColor) + y_constant += 15 im_drawer.text( - text=string1, xy=(canvas.size[0] - xRightOffset-d, 35*fontZoom), + text=string1, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), font=labelFont, fill=labelColor) + y_constant += 15 im_drawer.text( - text=string2, xy=(canvas.size[0] - xRightOffset-d, 50*fontZoom), + text=string2, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), font=labelFont, fill=labelColor) + y_constant += 15 if string3 != '': im_drawer.text( - text=string3, xy=(canvas.size[0] - xRightOffset-d, 65*fontZoom), + text=string3, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), font=labelFont, fill=labelColor) - + y_constant += 15 + if string4 != '': + im_drawer.text( + text=string4, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), + font=labelFont, fill=labelColor) def drawGeneBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): im_drawer = ImageDraw.Draw(canvas) -- cgit v1.2.3 From 355e5337330f57ee173aaf309805ca1b0ec0503c Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 14 Jan 2021 15:35:35 -0600 Subject: Fixed mistake where the mapping figure Transform text didn't have its X position set correctly --- wqflask/wqflask/marker_regression/display_mapping_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 864f3264..4df56190 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -1223,7 +1223,7 @@ class DisplayMappingResults(object): transform_text += "Invert +/-" im_drawer.text( - text=transform_text, xy=(canvas.size[0] - xRightOffset-d, y_constant*fontZoom), + text=transform_text, xy=(xLeftOffset, y_constant*fontZoom), font=labelFont, fill=labelColor) y_constant += 15 im_drawer.text( -- cgit v1.2.3 From 0bac313ba6a6c4cf04acf230641cc4208a386275 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 14 Jan 2021 15:53:53 -0600 Subject: Added some lines that check if salt is already bytes and convert it if necessary (this is caused by salt being passed to a function as bytes when an account is registered but being passed as a string when logging in) --- wqflask/wqflask/pbkdf2.py | 4 ++-- wqflask/wqflask/user_login.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/pbkdf2.py b/wqflask/wqflask/pbkdf2.py index aea5b06c..6346df03 100644 --- a/wqflask/wqflask/pbkdf2.py +++ b/wqflask/wqflask/pbkdf2.py @@ -2,15 +2,15 @@ import hashlib from werkzeug.security import safe_str_cmp as ssc - # Replace this because it just wraps around Python3's internal # functions. Added this during migration. def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc="sha1"): """Wrapper function of python's hashlib.pbkdf2_hmac. """ + dk = hashlib.pbkdf2_hmac(hashfunc, bytes(data, "utf-8"), # password - bytes(salt, "utf-8"), # salt + salt, iterations, keylen) return dk.hex() diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index bc608e84..041f1f11 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -39,8 +39,12 @@ def basic_info(): def encode_password(pass_gen_fields, unencrypted_password): + if isinstance(pass_gen_fields['salt'], bytes): + salt = pass_gen_fields['salt'] + else: + salt = bytes(pass_gen_fields['salt'], "utf-8") encrypted_password = pbkdf2.pbkdf2_hex(str(unencrypted_password), - pass_gen_fields['salt'], + salt, pass_gen_fields['iterations'], pass_gen_fields['keylength'], pass_gen_fields['hashfunc']) -- cgit v1.2.3 From db31d53421c033a9907d2c67bc8a0c3c911b5402 Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Thu, 14 Jan 2021 21:13:01 +0300 Subject: resize image in facilities page --- wqflask/wqflask/templates/facilities.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wqflask/wqflask/templates/facilities.html b/wqflask/wqflask/templates/facilities.html index 56b127f9..dc8d0ded 100644 --- a/wqflask/wqflask/templates/facilities.html +++ b/wqflask/wqflask/templates/facilities.html @@ -4,6 +4,14 @@ {% block css %} <link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" /> + +<style> + img[src="https://github.com/genenetwork/gn-docs/raw/master/general/help/octopus.jpg"] { + width:100%; + margin:20px 0px; +} +</style> + {% endblock %} {% block content %} -- cgit v1.2.3 From c228aff0cc9480f7b9ee46e54c9fef0f46299a3d Mon Sep 17 00:00:00 2001 From: zsloan Date: Sun, 17 Jan 2021 14:57:52 -0600 Subject: Set default description to avoid error in situations where description is None --- wqflask/wqflask/search_results.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index c4ea2921..9e8001cf 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -120,7 +120,9 @@ class SearchResultPage(object): trait_dict['hmac'] = hmac.data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) if this_trait.dataset.type == "ProbeSet": trait_dict['symbol'] = this_trait.symbol - trait_dict['description'] = this_trait.description_display + trait_dict['description'] = "N/A" + if this_trait.description_display: + trait_dict['description'] = this_trait.description_display trait_dict['location'] = this_trait.location_repr trait_dict['mean'] = "N/A" trait_dict['additive'] = "N/A" @@ -136,7 +138,9 @@ class SearchResultPage(object): elif this_trait.dataset.type == "Geno": trait_dict['location'] = this_trait.location_repr elif this_trait.dataset.type == "Publish": - trait_dict['description'] = this_trait.description_display + trait_dict['description'] = "N/A" + if this_trait.description_display: + trait_dict['description'] = this_trait.description_display trait_dict['authors'] = this_trait.authors trait_dict['pubmed_id'] = "N/A" if this_trait.pubmed_id: -- cgit v1.2.3 From 715d9137038887c6654a14d22dc0512bb01aaf86 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 17 Jan 2021 08:51:06 -0600 Subject: modify the main query in gene global search to add locus chr, locus mb and optimize the speed of query --- wqflask/wqflask/gsearch.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py index 9e46c0c5..6ff57563 100644 --- a/wqflask/wqflask/gsearch.py +++ b/wqflask/wqflask/gsearch.py @@ -1,4 +1,6 @@ import json +import datetime as dt +from types import SimpleNamespace from flask import Flask, g from base.data_set import create_dataset @@ -9,8 +11,9 @@ from base import webqtlConfig from utility import hmac -from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string from utility.benchmark import Bench +from utility.authentication_tools import check_resource_availability +from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string from utility.logger import getLogger logger = getLogger(__name__) @@ -42,15 +45,19 @@ class GSearch(object): ProbeSetXRef.LRS AS lrs, ProbeSetXRef.`Locus` AS locus, ProbeSetXRef.`pValue` AS pvalue, - ProbeSetXRef.`additive` AS additive - FROM Species, InbredSet, ProbeSetXRef, ProbeSet, ProbeFreeze, ProbeSetFreeze, Tissue - WHERE InbredSet.`SpeciesId`=Species.`Id` - AND ProbeFreeze.InbredSetId=InbredSet.`Id` - AND ProbeFreeze.`TissueId`=Tissue.`Id` - AND ProbeSetFreeze.ProbeFreezeId=ProbeFreeze.Id - AND ( MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias,GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) ) - AND ProbeSet.Id = ProbeSetXRef.ProbeSetId - AND ProbeSetXRef.ProbeSetFreezeId=ProbeSetFreeze.Id + ProbeSetXRef.`additive` AS additive, + ProbeSetFreeze.Id AS probesetfreeze_id, + Geno.Chr as geno_chr, + Geno.Mb as geno_mb + FROM Species + INNER JOIN InbredSet ON InbredSet.`SpeciesId`=Species.`Id` + INNER JOIN ProbeFreeze ON ProbeFreeze.InbredSetId=InbredSet.`Id` + INNER JOIN Tissue ON ProbeFreeze.`TissueId`=Tissue.`Id` + INNER JOIN ProbeSetFreeze ON ProbeSetFreeze.ProbeFreezeId=ProbeFreeze.Id + INNER JOIN ProbeSetXRef ON ProbeSetXRef.ProbeSetFreezeId=ProbeSetFreeze.Id + INNER JOIN ProbeSet ON ProbeSet.Id = ProbeSetXRef.ProbeSetId + LEFT JOIN Geno ON ProbeSetXRef.Locus = Geno.Name AND Geno.SpeciesId = Species.Id + WHERE ( MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,ProbeSet.alias,ProbeSet.GenbankId, ProbeSet.UniGeneId, ProbeSet.Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) ) AND ProbeSetFreeze.confidentiality < 1 AND ProbeSetFreeze.public > 0 ORDER BY species_name, inbredset_name, tissue_name, probesetfreeze_name, probeset_name @@ -90,16 +97,16 @@ class GSearch(object): this_trait['additive'] = "N/A" if line[14] != "" and line[14] != None: this_trait['additive'] = '%.3f' % line[14] + this_trait['dataset_id'] = line[15] + this_trait['locus_chr'] = line[16] + this_trait['locus_mb'] = line[17] #dataset = create_dataset(line[3], "ProbeSet", get_samplelist=False) #trait_id = line[4] #with Bench("Building trait object"): - trait_ob = create_trait(dataset_name=this_trait['dataset'], name=this_trait['name'], get_qtl_info=True, get_sample_info=False) - if not trait_ob: - continue max_lrs_text = "N/A" - if trait_ob.locus_chr != "" and trait_ob.locus_mb != "": - max_lrs_text = "Chr" + str(trait_ob.locus_chr) + ": " + str(trait_ob.locus_mb) + if this_trait['locus_chr'] != None and this_trait['locus_mb'] != None: + max_lrs_text = "Chr" + str(this_trait['locus_chr']) + ": " + str(this_trait['locus_mb']) this_trait['max_lrs_text'] = max_lrs_text trait_list.append(this_trait) -- cgit v1.2.3 From 6749974cccdf10fc300c4265720dfd147db88989 Mon Sep 17 00:00:00 2001 From: uditgulati Date: Sun, 17 Jan 2021 08:57:12 -0600 Subject: add dataset object creation, permission check in global search code itself which takes the load off creating Trait object --- wqflask/wqflask/gsearch.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py index 6ff57563..2b8d4bc1 100644 --- a/wqflask/wqflask/gsearch.py +++ b/wqflask/wqflask/gsearch.py @@ -68,6 +68,7 @@ class GSearch(object): re = g.db.execute(sql).fetchall() trait_list = [] + dataset_to_permissions = {} with Bench("Creating trait objects"): for i, line in enumerate(re): this_trait = {} @@ -101,9 +102,15 @@ class GSearch(object): this_trait['locus_chr'] = line[16] this_trait['locus_mb'] = line[17] - #dataset = create_dataset(line[3], "ProbeSet", get_samplelist=False) - #trait_id = line[4] - #with Bench("Building trait object"): + dataset_ob = SimpleNamespace(id=this_trait["dataset_id"], type="ProbeSet",species=this_trait["species"]) + if dataset_ob.id not in dataset_to_permissions: + permissions = check_resource_availability(dataset_ob) + dataset_to_permissions[dataset_ob.id] = permissions + else: + pemissions = dataset_to_permissions[dataset_ob.id] + if "view" not in permissions['data']: + continue + max_lrs_text = "N/A" if this_trait['locus_chr'] != None and this_trait['locus_mb'] != None: max_lrs_text = "Chr" + str(this_trait['locus_chr']) + ": " + str(this_trait['locus_mb']) -- cgit v1.2.3 From 5187e582721ddfbb1e864378823f2685748bf5f2 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 18 Jan 2021 11:15:33 +0300 Subject: Pass salt as bytes when testing pbkdf2_hex * wqflask/tests/unit/wqflask/test_pbkdf2.py (test_pbkdf2_hex): Make password salt bytes. Breaking change introduced in 0bac313ba. --- wqflask/tests/unit/wqflask/test_pbkdf2.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/wqflask/tests/unit/wqflask/test_pbkdf2.py b/wqflask/tests/unit/wqflask/test_pbkdf2.py index a33fbd4f..7ad6c83e 100644 --- a/wqflask/tests/unit/wqflask/test_pbkdf2.py +++ b/wqflask/tests/unit/wqflask/test_pbkdf2.py @@ -11,43 +11,43 @@ class TestPbkdf2(unittest.TestCase): """ for password, salt, iterations, keylen, expected_value in [ - ('password', 'salt', 1, 20, + ('password', b'salt', 1, 20, '0c60c80f961f0e71f3a9b524af6012062fe037a6'), - ('password', 'salt', 2, 20, + ('password', b'salt', 2, 20, 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), - ('password', 'salt', 4096, 20, + ('password', b'salt', 4096, 20, '4b007901b765489abead49d926f721d065a429c1'), ('passwordPASSWORDpassword', - 'saltSALTsaltSALTsaltSALTsaltSALTsalt', + b'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 25, '3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038'), - ('pass\x00word', 'sa\x00lt', 4096, 16, + ('pass\x00word', b'sa\x00lt', 4096, 16, '56fa6aa75548099dcc37d7f03425e0c3'), - ('password', 'ATHENA.MIT.EDUraeburn', 1, 16, + ('password', b'ATHENA.MIT.EDUraeburn', 1, 16, 'cdedb5281bb2f801565a1122b2563515'), - ('password', 'ATHENA.MIT.EDUraeburn', 1, 32, + ('password', b'ATHENA.MIT.EDUraeburn', 1, 32, ('cdedb5281bb2f80' '1565a1122b256351' '50ad1f7a04bb9f3a33' '3ecc0e2e1f70837')), - ('password', 'ATHENA.MIT.EDUraeburn', 2, 16, + ('password', b'ATHENA.MIT.EDUraeburn', 2, 16, '01dbee7f4a9e243e988b62c73cda935d'), - ('password', 'ATHENA.MIT.EDUraeburn', 2, 32, + ('password', b'ATHENA.MIT.EDUraeburn', 2, 32, ('01dbee7f4a9e243e9' '88b62c73cda935da05' '378b93244ec8f48a99' 'e61ad799d86')), - ('password', 'ATHENA.MIT.EDUraeburn', 1200, 32, + ('password', b'ATHENA.MIT.EDUraeburn', 1200, 32, ('5c08eb61fdf71e' '4e4ec3cf6ba1f55' '12ba7e52ddbc5e51' '42f708a31e2e62b1e13')), - ('X' * 64, 'pass phrase equals block size', 1200, 32, + ('X' * 64, b'pass phrase equals block size', 1200, 32, ('139c30c0966bc32ba' '55fdbf212530ac9c5' 'ec59f1a452f5cc9ad' '940fea0598ed1')), - ('X' * 65, 'pass phrase exceeds block size', 1200, 32, + ('X' * 65, b'pass phrase exceeds block size', 1200, 32, ('9ccad6d468770cd' '51b10e6a68721be6' '11a8b4d282601db3' -- cgit v1.2.3 From 8ed5d0e89cead10b03e5660c8eb87cf58a173436 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 18 Jan 2021 11:20:02 +0300 Subject: Remove extra newlines in PR and issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 6 ------ .github/ISSUE_TEMPLATE/feature_request.md | 11 ----------- .github/ISSUE_TEMPLATE/user_story.md | 4 ---- .github/PULL_REQUEST_TEMPLATE.md | 3 --- 4 files changed, 24 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 48bad39b..af60c290 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,27 +8,21 @@ assignees: '' --- **Describe the bug** - <!-- A clear and concise description of what the bug is. --> **To Reproduce** - <!-- Steps to reproduce the behavior --> **Expected behavior** - <!-- A clear and concise description of what you expected to happen. --> **Screenshots** - <!-- If applicable, add screenshots to help explain your problem. --> **Environment setup (please complete the following information):** - <!-- - OS: [e.g. Linux] --> <!-- - Guix Version (optional) --> <!-- - [Anything else you think is relevant] --> **Additional context** - <!-- Add any other context about the problem here. --> diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index eb6c3e4b..813974c1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -8,34 +8,23 @@ assignees: '' --- ## Is your feature request related to a problem? Please describe. - <!-- A clear and concise description of what the problem is. --> - <!-- Example: I'm always frustrated when [...] --> ## Describe the solution you'd like - <!-- A clear and concise description of what you want to happen. --> ## Describe alternatives you've considered - <!-- A clear and concise description of any alternative solutions or features you've considered. --> ## User Stories (optional) - <!-- Example: --> - <!-- As a _[role or persona]_, I want _[goal/ need]_ so that _[why]_ --> - <!-- **Feature:** _[Brief description of feature]_ --> - <!-- _[Any additional descriptions on feature]_ --> - <!-- **Scenario:** - Please use _[Gherkin](https://cucumber.io/docs/gherkin/reference/)_ here --> ## Additional context - <!-- Add any other context or screenshots about the feature request here. --> diff --git a/.github/ISSUE_TEMPLATE/user_story.md b/.github/ISSUE_TEMPLATE/user_story.md index 52ae775d..d46976ba 100644 --- a/.github/ISSUE_TEMPLATE/user_story.md +++ b/.github/ISSUE_TEMPLATE/user_story.md @@ -6,11 +6,7 @@ labels: '' assignees: '' --- - <!-- As a _[role or persona]_, I want _[goal/ need]_ so that _[why]_ --> - <!-- **Feature:** _[Brief description of feature]_ --> - <!-- _[Any additional descriptions on feature]_ --> - <!-- **Scenario:** Please use _[Gherkin](https://cucumber.io/docs/gherkin/reference/)_ here --> diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f3371183..926b0548 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,15 +6,12 @@ assurance checks that should be done. What are the expectations --> #### Any background context you want to provide? - <!-- Anything the reviewer should be aware of ahead of testing --> #### What are the relevant pivotal tracker stories? - <!-- Does this PR track anything anywhere? --> #### Screenshots (if appropriate) #### Questions - <!-- Are there any questions for the reviewer --> -- cgit v1.2.3 From 42fd88d0e57462d4538ae328564fcc55da761991 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 18 Jan 2021 11:30:36 +0300 Subject: Revert "resize image in facilities page" This reverts commit db31d53421c033a9907d2c67bc8a0c3c911b5402. --- wqflask/wqflask/templates/facilities.html | 8 -------- 1 file changed, 8 deletions(-) diff --git a/wqflask/wqflask/templates/facilities.html b/wqflask/wqflask/templates/facilities.html index dc8d0ded..56b127f9 100644 --- a/wqflask/wqflask/templates/facilities.html +++ b/wqflask/wqflask/templates/facilities.html @@ -4,14 +4,6 @@ {% block css %} <link rel="stylesheet" type="text/css" href="/static/new/css/markdown.css" /> - -<style> - img[src="https://github.com/genenetwork/gn-docs/raw/master/general/help/octopus.jpg"] { - width:100%; - margin:20px 0px; -} -</style> - {% endblock %} {% block content %} -- cgit v1.2.3 From 3b2a835fce1cda94f0649d45297867ddb5994731 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 21 Jan 2021 12:50:28 -0600 Subject: Fixed the Select Top Rows feature to use DataTables API instead of JQuery --- .../static/new/javascript/search_results.js | 48 +++++++++++++--------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/search_results.js b/wqflask/wqflask/static/new/javascript/search_results.js index 05dcfda5..ecb1220d 100644 --- a/wqflask/wqflask/static/new/javascript/search_results.js +++ b/wqflask/wqflask/static/new/javascript/search_results.js @@ -95,29 +95,37 @@ $(function() { $('#select_top').keyup(function(){ num_rows = $(this).val() + if (num_rows = parseInt(num_rows)){ - i = 0 - $('#trait_table > tbody > tr').each(function(){ - if (i < num_rows) { - $(this).find('.trait_checkbox').prop("checked", true) - if (!$(this).closest('tr').hasClass('selected')) { - $(this).closest('tr').addClass('selected') - } - } - else { - if ($(this).closest('tr').hasClass('selected')) { - $(this).closest('tr').removeClass('selected') - $(this).find('.trait_checkbox').prop("checked", false) - } - } - i += 1 - }); + table_api = $('#trait_table').DataTable(); + + check_cells = table_api.column(0).nodes().to$(); + for (let i = 0; i < num_rows; i++) { + check_cells[i].childNodes[0].checked = true; + } + + check_rows = table_api.rows().nodes(); + for (let i=0; i < num_rows; i++) { + if (check_rows[i].classList.contains("selected")){ + continue + } else { + check_rows[i].classList.add("selected") + } + } + for (let i = num_rows; i < check_rows.length; i++){ + check_cells[i].childNodes[0].checked = false; + if (check_rows[i].classList.contains("selected")){ + check_rows[i].classList.remove("selected") + } + } } else { - $('#trait_table > tbody > tr').each(function(){ - $(this).closest('tr').removeClass('selected') - $(this).find('.trait_checkbox').prop("checked", false) - }); + for (let i = 0; i < check_rows.length; i++){ + check_cells[i].childNodes[0].checked = false; + if (check_rows[i].classList.contains("selected")){ + check_rows[i].classList.remove("selected") + } + } } change_buttons(); }); -- cgit v1.2.3 From af386b6d11872d633cd23185c22e8f9f8d650fd2 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 21 Jan 2021 14:27:46 -0600 Subject: Adjusted Search Result table column widths and header alignments --- wqflask/wqflask/templates/search_result_page.html | 37 ++++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index b8f89121..eb42eb3a 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -274,41 +274,42 @@ } }, { - 'title': "Location", + 'title': "<div style='text-align: right;'>Location</div>", 'type': "natural-minus-na", 'width': "125px", 'data': "location" }, { - 'title': "Mean", + 'title': "<div style='text-align: right;'>Mean</div>", 'type': "natural-minus-na", - 'width': "40px", + 'width': "30px", 'data': "mean", 'orderSequence': [ "desc", "asc"] }, { - 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", + 'title': "<div style='text-align: right;'>Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a></div><div style='text-align: right;'>LOD  </div>", 'type': "natural-minus-na", 'data': "lod_score", 'width': "60px", 'orderSequence': [ "desc", "asc"] }, { - 'title': "Peak Location", + 'title': "<div style='text-align: right;'>Peak Location</div>", 'type': "natural-minus-na", 'width': "125px", 'data': "lrs_location" }, { - 'title': "Effect Size<a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", + 'title': "<div style='text-align: right;'>Effect <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a></div><div style='text-align: right;'>Size  </div>", 'type': "natural-minus-na", 'data': "additive", - 'width': "90px", + 'width': "60px", 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Publish' %}, { 'title': "Description", 'type': "natural", + 'width': "500px", 'data': null, 'render': function(data, type, row, meta) { try { @@ -319,16 +320,16 @@ } }, { - 'title': "Mean", + 'title': "<div style='text-align: right;'>Mean</div>", 'type': "natural-minus-na", - 'width': "110px", + 'width': "30px", 'data': "mean", 'orderSequence': [ "desc", "asc"] }, { 'title': "Authors", 'type': "natural", - 'width': "500px", + 'width': "400px", 'data': null, 'render': function(data, type, row, meta) { author_list = data.authors.split(",") @@ -341,10 +342,10 @@ } }, { - 'title': "Year", + 'title': "<div style='text-align: right;'>Year</div>", 'type': "natural-minus-na", 'data': null, - 'width': "80px", + 'width': "25px", 'render': function(data, type, row, meta) { if (data.pubmed_id != "N/A"){ return '<a href="' + data.pubmed_link + '">' + data.pubmed_text + '</a>' @@ -355,34 +356,34 @@ 'orderSequence': [ "desc", "asc"] }, { - 'title': "Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>LOD", + 'title': "<div style='text-align: right;'>Peak <a href=\"{{ url_for('glossary_blueprint.glossary') }}#LRS\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a></div><div style='text-align: right;'>LOD  </div>", 'type': "natural-minus-na", 'data': "lod_score", 'width': "60px", 'orderSequence': [ "desc", "asc"] }, { - 'title': "Peak Location", + 'title': "<div style='text-align: right;'>Peak Location</div>", 'type': "natural-minus-na", 'width': "120px", 'data': "lrs_location" }, { - 'title': "Effect Size<a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>", + 'title': "<div style='text-align: right;'>Effect <a href=\"{{ url_for('glossary_blueprint.glossary') }}#A\" target=\"_blank\" style=\"color: white;\"> <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a></div><div style='text-align: right;'>Size  </div>", 'type': "natural-minus-na", - 'width': "120px", + 'width': "60px", 'data': "additive", 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Geno' %}, { - 'title': "Location", + 'title': "<div style='text-align: right;'>Location</div>", 'type': "natural-minus-na", 'width': "120px", 'data': "location" }{% endif %} ], "order": [[1, "asc" ]], - 'sDom': "itir", + 'sDom': "iti", "autoWidth": true, "bSortClasses": false, "scrollY": "100vh", -- cgit v1.2.3 From 1ad00938cafb2f0511658397050f6e938854d194 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 21 Jan 2021 14:31:14 -0600 Subject: Changed CSS for show/hide column buttons so it's more obvious when one is selected --- wqflask/wqflask/static/new/css/trait_list.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/css/trait_list.css b/wqflask/wqflask/static/new/css/trait_list.css index b83655da..b765cdd4 100644 --- a/wqflask/wqflask/static/new/css/trait_list.css +++ b/wqflask/wqflask/static/new/css/trait_list.css @@ -12,7 +12,7 @@ div.show-hide-container { } button.active { - background: #e5e5e5; + background: #BEBEBE; -webkit-box-shadow: inset 0px 0px 5px #c1c1c1; -moz-box-shadow: inset 0px 0px 5px #c1c1c1; box-shadow: inset 0px 0px 5px #c1c1c1; -- cgit v1.2.3 From db2d9d81493750971ccfe59934dcb6e00f67c521 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 21 Jan 2021 15:15:12 -0600 Subject: Decreased the width of the Authors column some --- wqflask/wqflask/templates/search_result_page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index eb42eb3a..9b36568c 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -329,7 +329,7 @@ { 'title': "Authors", 'type': "natural", - 'width': "400px", + 'width': "300px", 'data': null, 'render': function(data, type, row, meta) { author_list = data.authors.split(",") -- cgit v1.2.3 From 9f12da2623c3ca9156300c825fe0f86ad08bb76e Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 21 Jan 2021 15:26:26 -0600 Subject: Added modified Scroller CSS to trait_list.css in order to add the text showing current row when scrolling and remove a 0 that was appearing below the table --- wqflask/wqflask/static/new/css/trait_list.css | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/static/new/css/trait_list.css b/wqflask/wqflask/static/new/css/trait_list.css index b765cdd4..c7249721 100644 --- a/wqflask/wqflask/static/new/css/trait_list.css +++ b/wqflask/wqflask/static/new/css/trait_list.css @@ -17,4 +17,38 @@ button.active { -moz-box-shadow: inset 0px 0px 5px #c1c1c1; box-shadow: inset 0px 0px 5px #c1c1c1; outline: none; - } \ No newline at end of file +} + +div.dts { + display:block !important +} + +div.dts div.dts_loading { + z-index:1 +} + +div.dts div.dts_label { + position:absolute; + right:10px; + background:rgba(0,0,0,0.8); + color:white; + box-shadow:3px 3px 10px rgba(0,0,0,0.5); + text-align:right; + border-radius:3px; + padding:0.4em; + z-index:2; + display:none +} + +div.dts div.dataTables_scrollBody { + background:repeating-linear-gradient(45deg, #edeeff, #edeeff 10px, #fff 10px, #fff 20px) +} + +div.dts div.dataTables_scrollBody table { + z-index:2 +} + +div.dts div.dataTables_paginate,div.dts div.dataTables_length{ + display:none +} + -- cgit v1.2.3